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
  • How can I implement the searchForFood API and retrieve attribute data?
  • Example
  • useFoodSearch
  • FoodSearch
  • Utility Methods
  • Result
Export as PDF
  1. Guides
  2. React Native SDK Docs
  3. V2

Search Food Item

You can utilize the searchForFood API to find food items based on their taste preferences by providing a search query.

How can I implement the searchForFood API and retrieve attribute data?

import { PassioSDK,} from '@passiolife/nutritionai-react-native-sdk-v2';


/**
     * Search the local database of foods with a given search term.
     * @param searchQuery - The search term to match against food item names.
     * @returns A `Promise` resolving to an array of food item names.
     */ 
    const searchFoods = await PassioSDK.searchForFood(query);

Example

To implement the searchForFood API and retrieve attribute data, you can modify the useFoodSearch custom hook to include these functionalities. Here's an updated version of your useFoodSearch hook with added comments and documentation annotations:

useFoodSearch


import { useState, useCallback, useEffect } from 'react';
import { useDebounce } from '../../utils/UseDebounce';
import {
  type PassioIDAttributes,
  PassioSDK,
  type FoodSearchResult,
} from '@passiolife/nutritionai-react-native-sdk-v2';

export interface FoodResult {
  passioIDAttributes: PassioIDAttributes;
  foodSearchResult: FoodSearchResult;
}

const useFoodSearch = () => {
  // State variables
  const [searchQuery, setSearchQuery] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(false);
  const [foodResults, setFoodResults] = useState<FoodResult[]>([]);
  const debouncedSearchTerm: string = useDebounce<string>(searchQuery, 300);

  // Clears search results and resets state
  const cleanSearch = useCallback(() => {
    setSearchQuery('');
    setFoodResults([]);
    setLoading(false);
  }, []);

  // Calls the search API based on the input value
  const callSearchApi = useCallback(
    async (query: string) => {
      // Check if the query is not empty
      if (query.length > 0) {
        // Set loading state to indicate the start of the search
        setLoading(true);

        try {
          // Fetch food results from the PassioSDK based on the query
          const searchFoods = await PassioSDK.searchForFood(query);

          // Process each search result, including fetching attributes
          const result: (FoodResult | null)[] = await Promise.all(
            searchFoods.map(async (item) => {
              // Retrieve attributes for the current food item
              const attribute = await PassioSDK.getAttributesForPassioID(
                item.passioID
              );

              // If attributes exist, create a FoodResult object, otherwise, return null
              if (attribute) {
                return {
                  passioIDAttributes: attribute,
                  foodSearchResult: item,
                };
              } else {
                return null;
              }
            })
          );

          // Filter out null values (where attributes were not found) and update state
          setFoodResults(result.filter((item): item is FoodResult => !!item));
        } catch (error) {
          // Handle errors, e.g., network issues or API failures
          setFoodResults([]);
        } finally {
          // Reset loading state to indicate the end of the search
          setLoading(false);
        }
      } else {
        // If the query is empty, reset the search state
        cleanSearch();
      }
    },
    [cleanSearch]
  );

  // Initiates a new search with the provided query
  const onSearchFood = useCallback(
    async (q: string) => {
      if (q.length > 0) {
        setSearchQuery(q);
        setFoodResults([]);
      } else {
        cleanSearch();
      }
    },
    [cleanSearch]
  );

  // Effect for handling debounced search term changes
  useEffect(() => {
    if (debouncedSearchTerm.length > 0) {
      callSearchApi(debouncedSearchTerm);
    } else {
      cleanSearch();
    }
  }, [callSearchApi, debouncedSearchTerm, cleanSearch]);

  return {
    loading,
    foodResults,
    searchQuery,
    cleanSearch,
    onSearchFood,
  };
};

export default useFoodSearch;

FoodSearch

import React from 'react';
import {
  ActivityIndicator,
  FlatList,
  Pressable,
  StyleSheet,
  Text,
  TextInput,
} from 'react-native';
import {
  PassioIconView,
  IconSize,
} from '@passiolife/nutritionai-react-native-sdk-v2';
import { SafeAreaView } from 'react-native-safe-area-context';
import useFoodSearch, { type FoodResult } from './useFoodSearch';

// FoodSearchScreen component
export const FoodSearchScreen = () => {
  // Destructure values from the custom hook
  const { searchQuery, onSearchFood, foodResults, loading } = useFoodSearch();

  // Get styles object from the searchStyle function
  const styles = searchStyle();

  // Function to render each item in the FlatList
  const renderItem = ({ item }: { item: FoodResult }) => {
    return (
      <Pressable style={styles.itemContainer}>
        <PassioIconView
          style={styles.itemIcon}
          config={{
            passioID: item.passioIDAttributes.passioID,
            iconSize: IconSize.PX90,
            passioIDEntityType: item.passioIDAttributes.entityType,
          }}
        />
        <Text style={styles.itemFoodName}>{item.foodSearchResult.name}</Text>
      </Pressable>
    );
  };

  // Display loading indicator when results are empty and loading is true
  const renderLoading = () => {
    return <>{loading ? <ActivityIndicator /> : null}</>;
  };

  // Render the component
  return (
    <SafeAreaView>
      {/* Search input */}
      <TextInput
        value={searchQuery}
        style={styles.textInput}
        placeholder="Search Food"
        onChangeText={onSearchFood}
      />

      {/* FlatList to display search results */}
      <FlatList
        data={foodResults}
        renderItem={renderItem}
        ListEmptyComponent={renderLoading}
        keyExtractor={(item, index) => item.result.passioID.toString() + index}
      />
    </SafeAreaView>
  );
};

// Styles for the component
const searchStyle = () =>
  StyleSheet.create({
    itemContainer: {
      padding: 12,
      backgroundColor: 'white',
      marginVertical: 4,
      marginHorizontal: 16,
      flexDirection: 'row',
      alignItems: 'center',
    },
    itemFoodName: {
      flex: 1,
      textTransform: 'capitalize',
      marginHorizontal: 8,
      fontSize: 16,
    },
    itemIcon: {
      height: 40,
      width: 40,
    },
    textInput: {
      backgroundColor: 'white',
      paddingHorizontal: 16,
      margin: 16,
    },
  });

Utility Methods

import { useState, useEffect } from 'react';

// Hook
// T is a generic type for value parameter, our case this will be string
export function useDebounce<T>(value: T, delay: number): T {
  // State and setters for debounced value
  const [debouncedValue, setDebouncedValue] = useState<T>(value);
  useEffect(
    () => {
      // Update debounced value after delay
      const handler = setTimeout(() => {
        setDebouncedValue(value);
      }, delay);
      // Cancel the timeout if value changes (also on delay change or unmount)
      // This is how we prevent debounced value from updating if value is changed ...
      // .. within the delay period. Timeout gets cleared and restarted.
      return () => {
        clearTimeout(handler);
      };
    },
    [value, delay] // Only re-call effect if value or delay changes
  );
  return debouncedValue;
}

Result

PreviousFood ImageNextQuick Scan

Last updated 10 months ago