MealVeda Day 2: Core Features - Implementing the Meal Collection System

Day 2 focused on building MealVeda's core functionality: the meal collection system with real-time nutrition tracking. The challenge was creating a flexible data structure that supports ingredient-level customization while maintaining performance.
Meal Data Architecture
Implemented a hierarchical data model where meals contain ingredients, and ingredients connect to nutrition databases:
class Meal {
final String name;
final List<Ingredient> ingredients;
final MealCategory category; // breakfast, lunch, dinner, snacks
NutritionSummary get nutritionSummary {
return ingredients.fold(
NutritionSummary.empty(),
(summary, ingredient) => summary.add(ingredient.nutrition)
);
}
}
class Ingredient {
final String name;
final double amount; // 240.0
final String unit; // "gms"
final NutritionData nutritionPer100g;
NutritionData get nutrition {
return nutritionPer100g.scale(amount / 100);
}
}
Real-Time Nutrition Calculation
The dashboard displays live nutrition progress as users add meals. Implemented efficient calculation using reactive state management:
class NutritionTracker extends ChangeNotifier {
final List<Meal> _dailyMeals = [];
NutritionSummary get dailyTotal {
return _dailyMeals.fold(
NutritionSummary.empty(),
(total, meal) => total.add(meal.nutritionSummary)
);
}
void addMeal(Meal meal) {
_dailyMeals.add(meal);
notifyListeners(); // Triggers UI update
}
}
Nutrition API Integration
Connected to open-source nutrition databases using a service layer approach:
class NutritionService {
static const String baseUrl = 'https://api.edamam.com/api/nutrition-data';
Future<NutritionData> getNutritionData(String ingredient, double amount) async {
try {
final response = await http.get(
Uri.parse('$baseUrl?ingr=$ingredient&app_id=$appId&app_key=$appKey')
);
if (response.statusCode == 200) {
return NutritionData.fromJson(jsonDecode(response.body));
}
throw Exception('Failed to fetch nutrition data');
} catch (e) {
// Fallback to local database
return await _getLocalNutritionData(ingredient);
}
}
}
Meal Collection UI Implementation
Built the meal collection screen with expandable cards showing nutrition summaries:
Widget buildMealCard(Meal meal) {
return Card(
child: ExpansionTile(
title: Text(meal.name, style: Theme.of(context).textTheme.headline6),
subtitle: Text('${meal.calories} cal • ${meal.protein}g protein'),
children: [
...meal.ingredients.map((ingredient) => ListTile(
title: Text(ingredient.name),
trailing: Text('${ingredient.amount}${ingredient.unit}'),
)),
ButtonBar(
children: [
TextButton(
onPressed: () => _editMeal(meal),
child: Text('Edit Meal'),
),
TextButton(
onPressed: () => _addToDay(meal),
child: Text('Add to Day'),
),
],
),
],
),
);
}
Performance Optimizations
Cached nutrition calculations to avoid repeated API calls
Used
ListView.builder()for efficient scrolling of large meal collectionsImplemented local storage using
shared_preferencesfor offline functionalityBackground computation for nutrition updates to maintain 60fps UI
Color-Coded Nutrition Display
Implemented visual feedback system with consistent color coding:
class NutritionColors {
static const Color calories = Color(0xFFFF9500); // Orange
static const Color carbs = Color(0xFF34C759); // Green
static const Color protein = Color(0xFF007AFF); // Blue
static const Color fat = Color(0xFFFF3B30); // Red
static const Color fiber = Color(0xFFAF52DE); // Purple
}
Day 2 Technical Achievements:
Hierarchical meal/ingredient data structure
Real-time nutrition calculation and display
API integration with fallback to local data
Responsive UI with background computation
Offline-first architecture with local persistence
Next: Implementing the advanced meal selection interface with bottom sheet interactions.



