androidreact-native

How to filter API data in React Native


I am trying to filter my API data according to my Text input in search but I am not able to. I tried multiple references and read different documentation on filter but were not useful enough.

import { useNavigation } from '@react-navigation/native';
import React, { useEffect, useState } from 'react';
import { Dimensions, StyleSheet, TouchableOpacity, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { Carousal, Heading, Input, List, Map } from '../components';
import { baseStyle, routes, theme } from '../config';
import axios from 'axios';

export const NearMe = () => {

  const [responseData, setResponseData] = useState(undefined);
  const [searchData, setSearchData] = useState([]);
  const [search, setSearch] = useState('');

  const getAPIData = async () => {
    try {
      const url = "https://6655-119-157-85-241.ngrok-free.app/listing";
      let result = await fetch(url);
      result = await result.json();
      return result;
    } catch (error) {
      console.log(`error`)
      console.error(error)
    }
  }
  useState(async () => {
    // const data = await getAPIData();
    // setData(data);
    try {
      const url = "https://75b5-119-157-84-191.ngrok-free.app/listing";
      let result = await fetch(url);
      result = await result.json();
      setResponseData(result.data);
      setSearchData(result.data);
    } catch (error) {
      console.log(`error`)
      console.error(error)
    }
  })

  console.log(responseData)

  const onSearch=(text)=>{
    setSearch(
      responseData.filter((item) =>
      item.listing_area.toUpperCase().includes(text.toUpperCase()))
    );
  }


  // axios.get('https://31bc-119-157-84-10.ngrok-free.app/listing')
  // .then(response=> {
  //   //Handle success
  //   console.log(response.data);
  // })
  // .catch(error => {
  //   console.log(error)
  // });

  // useEffect(() => {
  //   axios.get('https://31bc-119-157-84-10.ngrok-free.app/listing')
  //     .then(response => {
  //       // Handle success
  //       console.log(response.data);
  //     })
  //     .catch(error => {
  //       // Handle error
  //       console.log(error);
  //     });
    
    
  //   }, []);

  // console.log("dasdadsa");
  // console.log(responseData);
  // return false;
  // const data = {"success":true,"data":[{"id":2,"listing_title":"Zahid Nehari","listing_description":"test test test","listing_category":"Food","listing_area":"Saddar","listing_location":"Saddar"},{"id":1,"listing_title":"Zahid Nehari","listing_description":"test test test","listing_category":"Food","listing_area":"Saddar","listing_location":"Saddar"}],"message":"Data Found"};

  const [carousalView, setCarousalView] = useState(true);
  const navigation = useNavigation();

  const toogleView = () => {
    setCarousalView(!carousalView);
  };

  const navigationHandler = (data) => {
    navigation.navigate(routes.VENUE_PROFILE, data);
  };
  //console.log(responseData);
  return (
    <SafeAreaView edges={['top', 'left', 'right']} style={styles.container}>
      <View style={styles.mapContainer}>
        <Map width="100%" height="100%" />
        <Input placeholder="Search area"
        placeholderTextColor="#aaaaaa"
        style={styles.input}
        value={search}
        onChangeText={search=>{
          onSearch(txt);
        }} />
      </View>
      <View style={styles.headingContainer}>
        <Heading style={styles.heading}>Things To Do</Heading>
        <TouchableOpacity onPress={toogleView}>
          <Heading style={{ ...styles.heading, color: theme.colors.blue }}>
            {carousalView ? 'List View' : 'Carousel View'}
          </Heading>
        </TouchableOpacity>
      </View>
      {carousalView ? (
        <Carousal data={responseData} onPress={navigationHandler} />

      ) : (
        <List data={responseData} onPress={navigationHandler} />
      )}
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingHorizontal: baseStyle.paddingHorizontal(10),
  },
  mapContainer: {
    width: '100%',
    height: (Dimensions.get('window').height * 50) / 100,
  },
  input: {
    position: 'absolute',
    top: 20,
    width: '100%',
    alignSelf: 'center',
    paddingLeft: baseStyle.paddingLeft(15),
    backgroundColor: theme.colors.lightGrey,
    color: theme.colors.black,
  },
  heading: {
    fontSize: baseStyle.fontSize(14),
    lineHeight: baseStyle.lineHeight(17),
  },
  headingContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginTop: baseStyle.marginTop(20),
  },
});

I am getting response in my API and data is displayed properly in carousel view as well as list view the problem is my search input is not working. What could be the solution to it?


Solution

  • It seems like you're trying to filter your data based on the listing_area property of each item. However, in your onSearch function, you're setting the search state to the filtered data, but it seems like search is meant to be the current search text, not the filtered data.

    Instead, you should be setting searchData (which I assume is meant to be the currently displayed data) to the filtered data.

    You might do that:

    const onSearch = (text) => {
      setSearch(text);
      setSearchData(
        responseData.filter((item) =>
          item.listing_area.toUpperCase().includes(text.toUpperCase())
        )
      );
    };
    

    Then, in your render method, you should use searchData instead of responseData when passing data to the Carousal and List components:

    <Carousal data={searchData} onPress={navigationHandler} />
    <List data={searchData} onPress={navigationHandler} />
    

    This way, the displayed data will update as you type in the search field.

    Also, make sure that your text change handler for the Input component is calling onSearch, not search:

    onChangeText={text => onSearch(text)}
    

    Also, I have some advice for you: make sure to clean up your code. Get rid of any unused segments and comment lines you no longer need. It's also helpful to break your code into smaller, more organized sections for clarity and ease of use.