Passio Nutrition-AI
  • Nutrition-AI SDK Overview
  • Guides
    • Nutrition AI SDK
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Nutrition Facts scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
        • User created foods and reports
    • iOS SDK Docs
      • Before getting started
      • Getting the ml models to the device
      • Run the demos first
      • Adding Passio SDK into your project
      • Initialize and configure the SDK
      • Start/Stop food detection
      • Food Recognition Delegate
      • Migration from SDK 1.4.X to 2.x
      • SDK API
      • Quick Start Guide
        • Installation
        • Configure the SDK (UIKit)
        • Recognise food using image
        • Food Details
    • Android SDK Docs
      • Getting started
        • Include the library
        • Camera
        • SDK Initialization and Configuration
        • Food detection session
        • Visual, Barcode and Packaged Food detection
        • Nutritional Database
        • Sandbox app
      • Troubleshooting on Android
      • Migration from SDK version 1.4.x to 2.x
      • Quick Start Guide
        • Importing the Android SDK to a project
        • Configure SDK and handle the result
        • RecognizeImageRemote
        • Food Details
    • React Native SDK Docs
      • Getting Started
        • Installation
        • SDK Initialization and Configuration
      • API Reference
        • configure & requestCameraAuthorization
        • recognizeImageRemote
        • searchForFood & searchForFoodSemantic
        • startFoodDetection
          • FoodDetectionEvent
        • fetchFoodItemForProductCode
        • fetchFoodItemForRefCode
        • fetchFoodItemForDataInfo
        • startNutritionFactsDetection
        • fetchFoodItemForPassioID
        • recognizeSpeechRemote
        • Fetch Nutrients
        • onDowloadingPassioModelCallBacks
        • detectFoodFromImageURI
        • addToPersonalization
        • updateLanguage
        • fetchHiddenIngredients
        • fetchVisualAlternatives
        • fetchPossibleIngredients
      • Properties
        • PassioFoodItem
        • PassioFoodDataInfo
        • PassioFoodAmount
        • PassioIngredient
        • PassioNutrients
        • UnitMass
        • ServingUnit
        • ServingSize
        • PassioSearchResult
        • NutritionFacts
        • PassioNutritionPreview
        • PassioSpeechRecognitionModel
        • PassioLogAction
        • PassioAdvisorFoodInfo
        • FoodCandidates
        • FoodDetectionEvent
        • NutritionDetectionEvent
        • DetectedCandidate
        • BarcodeCandidate
        • PackagedFoodCode
        • AmountEstimate
        • ImagesInfo
        • PassioStatus
        • FoodDetectionEvent
        • NutritionFacts
        • PassioMealPlan
        • PassioMealPlanItem
      • Nutriton Advisor
        • initConversation
        • sendMessage
        • sendImage
        • Guide
          • useNutritionAdvisor
        • Properties
          • PassioAdvisorResponse
          • PassioAdvisorMessageResultStatus
          • PassioAdvisorResultStatus
      • Quick Start Guide
        • Installation
        • Configure the SDK
        • RecognizeImageRemote
        • Food Detail
      • Guide
        • Integrate SDK Setup
        • Integrate Quick Scan
        • Integrate Food Search
        • Integrate Food Editor with Recipe
        • Integrate MealPlan
        • Integrate Suggestions
        • Integrate recognizeImageRemote
      • Components
        • DetectionCameraView
        • PassioIconView
      • Changelog
      • More
        • Display Macro Chart
          • MockFood
          • Utils PassioNutrient
        • Display Micro Progress
        • Getting nutrition value for a FoodItem
        • Getting nutrition value for a Recipe
        • Recalculate the nutrition value based on serving size options.
      • Migrations
        • Migrating from SDK 2.X to version 3.X
        • Structure Migrations From SDK 3.X to SDK 2.X
        • [Deprecated] Migrating from SDK 1.X to version 2.X
        • [Deprecated] Getting Started (v1)
          • Installation
          • SDK Initialization and Configuration
          • Start food detection
          • FoodDetectionEvent
          • Nutritional Database
      • Troubleshooting on RN
      • V2
        • Getting Started
          • Installation
          • SDK Initialization and Configuration
          • Start food detection
          • FoodDetectionEvent
        • RN SDK API
          • Properties
            • PersonalizedAlternative
            • FoodSearchResult
            • PassioNutrient
            • FoodDetectionEvent
            • DownloadModelCallBack
            • UPCProduct
            • ServingUnit
            • PassioStatus
            • PassioIDAttributes
            • PassioIDEntityType
            • PassioFoodItem
            • PassioRecipe
            • ServingSize
            • Measurement
            • UnitMass
            • NutritionFacts
        • Food Image
        • Search Food Item
        • Quick Scan
        • Multi Scan
        • MealPlan
        • Recipe
      • How do I Integrate a Passio SDK in EXPO?
    • Flutter SDK Docs
      • Getting Started
    • Before You Continue
    • Setup For Android
    • Initialize and configure the SDK
  • Fundamentals
    • Nutrition-AI Developer FAQ
      • Nutrition Data
      • Supported Phones
      • Security
      • Testing Volume Estimation
      • Testing Nutrition-AI SDK
      • Nutrition-AI Test Methodology
    • Nutrition API - Mobile SDK interoperability
      • JSON Response parsing
  • Versions
    • 3.2.4
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Nutrition Facts scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
        • User created foods and reports
    • 3.2.2
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Nutrition Facts scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
        • User created foods and reports
    • 3.2.0
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Nutrition Facts scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
    • 3.1.4
      • SDK Key and minimum requirements
      • Installation
      • Configure the SDK
      • Use Cases
        • Food recognition
        • Nutrition data
        • Barcode scanning
        • Search, Food Icons, RefCode
        • Speech recognition
        • Nutrition Advisor
        • Suggestions and Meal Plans
Powered by GitBook
On this page
  • Retrieve the PassioAttribute using the Passio ID. Within the food item, utilize the selectedQuantity and selectedServingUnit as the foundational values for obtaining nutrient values.
  • Example
  • useRecalculateServingSize
  • RecalculateServingSize
  • Utility Methods
Export as PDF
  1. Guides
  2. React Native SDK Docs
  3. More

Recalculate the nutrition value based on serving size options.

PreviousGetting nutrition value for a RecipeNextMigrations

Last updated 1 year ago

Retrieve the PassioAttribute using the Passio ID. Within the food item, utilize the selectedQuantity and selectedServingUnit as the foundational values for obtaining nutrient values.

Some ServingUnits are included within the food item as servings options from SDK, each accompanied by a value and unit name. For example, an apple might have default servings like large with a value of 200, medium with a value of 172, and small with a value of 157.

Example

useRecalculateServingSize

import {
  PassioSDK,
  type ServingUnit,
} from '@passiolife/nutritionai-react-native-sdk-v2';
import { useEffect, useRef, useState } from 'react';
import {
  calculateComputedWeightAmount,
  getMacroNutrientsFormPassioFoodItem,
  toFixed,
  type Nutrients,
} from './recalculateUtils';

export interface RecalculateServingSizeProps {
  passioID: string;
}

export const useRecalculateServingSize = ({
  passioID,
}: RecalculateServingSizeProps) => {
  // State to manage user input quantity
  const [userInputQuantity, setUserInputQuantity] = useState('');
  // State to manage selected serving value
  const [selectedServingValue, setSelectedServingValue] = useState(0);
  // State to manage selected serving unit
  const [selectedServingUnit, setSelectedServingUnit] = useState('');
  // State to store nutrients data
  const [nutrients, setNutrition] = useState<Nutrients[]>();
  // State to store serving units from PassioSDK
  const [sdkServingUnits, setSDKServingUnits] = useState<ServingUnit[]>();
  // Ref to store the base serving value for calculations
  const sdkBaseServingValueRef = useRef(0);

  // useEffect to initialize data on component mount
  useEffect(() => {
    // Function to initialize data from the PassioSDK
    const initialize = async () => {
      try {
        const { foodItem } =
          (await PassioSDK.getAttributesForPassioID(passioID)) || {};
        if (!foodItem) return;

        const { servingUnits, selectedQuantity, selectedUnit } = foodItem;
        setSDKServingUnits(servingUnits);
        setNutrition(getMacroNutrientsFormPassioFoodItem(foodItem));

        const baseServingValue = calculateComputedWeightAmount(
          selectedQuantity,
          servingUnits,
          selectedUnit
        );
        sdkBaseServingValueRef.current = baseServingValue;
        setSelectedServingValue(baseServingValue);
        setUserInputQuantity(selectedQuantity.toString());
        setSelectedServingUnit(selectedUnit);
      } catch (error) {
        console.error('Error initializing:', error);
      }
    };

    // Call the initialize function
    initialize();
  }, [passioID]);

  // Function to handle selection of a serving unit
  const onSelectServingItem = (servingUnit: ServingUnit) => {
    setSelectedServingValue(servingUnit.value);
    setSelectedServingUnit(servingUnit.unitName);
  };


  // Function to calculate updated nutrition value based on user input
  const getUpdatedNutritionValue = (item: Nutrients) => {
    const nutritionValue = item.unitMass?.value ?? 0;
    const ratio = calculateRatio(nutritionValue);
    const userInputServingSize =
      userInputQuantity.length > 0 ? Number(userInputQuantity) : 1;
    return toFixed(ratio * userInputServingSize);
  };

  // Function to calculate the ratio separately
  const calculateRatio = (nutritionValue: number): number => {
    return (
      (nutritionValue * selectedServingValue) / sdkBaseServingValueRef.current
    );
  };

  // Return the necessary values and functions
  return {
    nutrients,
    onSelectServingItem,
    sdkServingUnits,
    selectedServingUnit,
    getUpdatedNutritionValue,
    setUserInputQuantity,
    userInputQuantity,
  };
};

RecalculateServingSize

import React from 'react';
import { Pressable, StyleSheet, Text, TextInput, View } from 'react-native';
import { toFixed } from './recalculateUtils';
import { FlatList } from 'react-native';
import { useRecalculateServingSize } from './useRecaculateServingSize';

export interface RecalculateServingSizeProps {
  passioID: string;
}

export const RecalculateServingSize = ({
  passioID,
}: RecalculateServingSizeProps) => {
  // Destructuring values and functions from useRecalculateServingSize hook
  const {
    nutrients,
    onSelectServingItem,
    sdkServingUnits,
    selectedServingUnit,
    getUpdatedNutritionValue,
    setUserInputQuantity,
    userInputQuantity,
  } = useRecalculateServingSize({
    passioID: passioID,
  });

  return (
    <View style={styles.container}>
      {/* FlatList to display updated nutrition values */}
      <FlatList
        data={nutrients}
        extraData={userInputQuantity}
        renderItem={({ item }) => (
          <View style={styles.nutrition}>
            <Text style={styles.nutritionLabel}>{item.name}</Text>
            <Text>
              {getUpdatedNutritionValue(item)}
              {item.unitMass?.unit}
            </Text>
          </View>
        )}
      />
      {/* Section to input total serving quantity */}
      <View style={styles.nutritionTotalServing}>
        <Text style={styles.nutritionLabel}>Total Serving</Text>
        <TextInput
          style={styles.totalServingInput}
          placeholder="Total Serving"
          keyboardType="numeric"
          value={userInputQuantity.trim().toString()}
          onChangeText={(value) => {
            setUserInputQuantity(value.trim());
          }}
        />
      </View>
      {/* FlatList to display serving units */}
      <FlatList
        data={sdkServingUnits}
        horizontal
        renderItem={({ item }) => (
          <Pressable
            onPress={() => {
              onSelectServingItem(item);
            }}
          >
            <Text
              style={[
                styles.servingUnit,
                selectedServingUnit === item.unitName &&
                  styles.selectedServingUnit,
              ]}
            >
              {`${item.unitName} ${toFixed(item.value)}`}
            </Text>
          </Pressable>
        )}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: { flex: 1 },
  nutrition: { flex: 1, flexDirection: 'row', padding: 16 },
  servingUnit: { flexDirection: 'row', padding: 16 },
  nutritionTotalServing: {
    marginVertical: 16,
  },
  totalServingInput: { padding: 16, backgroundColor: 'white' },
  selectedServingUnit: {
    backgroundColor: 'blue',
    color: 'white',
    borderRadius: 24,
  },
  nutritionLabel: { flex: 1, textTransform: 'capitalize' },
});

Utility Methods

import type {
  PassioFoodItem,
  ServingUnit,
  UnitMass,
} from '@passiolife/nutritionai-react-native-sdk-v2';

// Define the types of nutrients
export type NutrientsTypes =
  | 'calories'
  | 'protein'
  | 'carbs'
  | 'fat'
  | 'saturatedFat'
  | 'transFat'
  | 'polyunsaturatedFat'
  | 'sodium'
  | 'fiber'
  | 'sugar'
  | 'sugarAdded'
  | 'vitaminD'
  | 'iron'
  | 'potassium'
  | 'vitaminA'
  | 'vitaminC'
  | 'alcohol'
  | 'sugarAlcohol'
  | 'vitaminB12'
  | 'vitaminB12Added'
  | 'vitaminB6'
  | 'vitaminE'
  | 'vitaminEAdded'
  | 'phosphorus'
  | 'iodine'
  | 'cholesterol';

// Define the structure of individual nutrients
export interface Nutrients {
  unitMass?: UnitMass;
  name: NutrientsTypes;
}

// Get a single nutrient from Passio Food Item
export const getNutrient = (
  foodItem: PassioFoodItem,
  name: NutrientsTypes
): Nutrients | null => {
  if (foodItem[name]) {
    return {
      name,
      unitMass: foodItem[name] ?? undefined,
    } as Nutrients;
  } else {
    return null;
  }
};

// Get multiple nutrients from Passio FoodItem
const getNutrients = (
  foodItem: PassioFoodItem,
  nutrientNames: NutrientsTypes[]
): Nutrients[] => {
  return nutrientNames
    .map((name) => {
      // General case for other nutrients
      return getNutrient(foodItem, name);
    })
    .filter((item): item is Nutrients => !!item);
};

// Get micro nutrients from Passio FoodItem
export const getMicroNutrientsFormPassioFoodItem = (
  foodItem: PassioFoodItem
): Nutrients[] => {
  const microNutrientNames: NutrientsTypes[] = [
    'saturatedFat',
    'transFat',
    'polyunsaturatedFat',
    'sodium',
    'fiber',
    'sugar',
    'sugarAdded',
    'vitaminD',
    'iron',
    'potassium',
    'vitaminA',
    'alcohol',
    'sugarAlcohol',
    'vitaminB12',
    'vitaminB12Added',
    'vitaminB6',
    'vitaminE',
    'vitaminEAdded',
    'phosphorus',
    'iodine',
    'cholesterol',
  ];
  return getNutrients(foodItem, microNutrientNames);
};

// Get micro nutrients from Passio FoodItem
export const getMacroNutrientsFormPassioFoodItem = (
  foodItem: PassioFoodItem
): Nutrients[] => {
  const macros: NutrientsTypes[] = ['calories', 'carbs', 'protein', 'fat'];
  return getNutrients(foodItem, macros);
};

// Function to format nutrient value
export const toFixed = (value?: number): number => {
  return Number((value ?? 0).toFixed(2));
};

export function calculateComputedWeightAmount(
  qty: number,
  servingUnits: ServingUnit[],
  unit: string
) {
  const result = qty * calculateMassOfServingUnit(servingUnits, unit);
  return result < 10 ? result : Math.ceil(result);
}

export function calculateMassOfServingUnit(
  servingUnits: ServingUnit[],
  selectedUnit: string
): number {
  let unit = 1;
  servingUnits?.forEach((value) => {
    if (value.unitName === selectedUnit) {
      unit = value.value;
    }
  });
  return unit;
}