Cole Perry
Cole Perry

Reputation: 160

React Native how do I make a Search Bar for a Flatlist?

I have been trying to create a search bar all day. I finally found this guide which seemed ok: https://blog.jscrambler.com/add-a-search-bar-using-hooks-and-flatlist-in-react-native/. I followed it through using my own API and I am not getting any errors exactly, but the code in this tutorial seems unfinished.

Here is what I have:

import React, { useEffect, useState } from 'react';
import { View, Text, FlatList, SafeAreaView, TextInput } from 'react-native';
import { Card, Header } from 'react-native-elements'
import { styles } from './styles.js';
import filter from 'lodash.filter';

const FormsScreen = ({navigation, route}) => {

  const [isLoading, setIsLoading] = useState(false);
  const [data, setData] = useState([]);
  const [query, setQuery] = useState('');
  const [fullData, setFullData] = useState([]);
  
  //Fetch all users from database
  useEffect(() =>{
    setIsLoading(true);
    fetch('http://10.0.2.2:5000/forms').then(response =>{
      if(response.ok){
        return response.json();
      }
    }).then(data => setFullData(data)).then(setIsLoading(false));
  }, []);


  function renderHeader() {
    return (
      <View
        style={{
          backgroundColor: '#fff',
          padding: 10,
          marginVertical: 10,
          borderRadius: 20
        }}
      >
        <TextInput
          autoCapitalize="none"
          autoCorrect={false}
          clearButtonMode="always"
          value={query}
          onChangeText={queryText => handleSearch(queryText)}
          placeholder="Search"
          style={{ backgroundColor: '#fff', paddingHorizontal: 20 }}
        />
      </View>
    );
  }

  const handleSearch = text => {
  const formattedQuery = text.toLowerCase();
  const filteredData = filter(fullData, form => {
    return contains(form, formattedQuery);
  });
  setData(filteredData);
  setQuery(text);
};

const contains = ({ ID }, query) => {
  console.log("ID was: "+ID);
  console.log("Query was: "+query);
  const id = ID;
  console.log('id was: '+id);
  if (id.toString().includes(query)) {
    return true;
  }

  return false;
};





  if (isLoading) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <ActivityIndicator size="large" color="#5500dc" />
      </View>
    );
  }
  else{
  return (

      <SafeAreaView>
        <Header
          leftComponent={{ icon: 'menu', color: '#fff' }}
          centerComponent={{ text: 'Request Forms', style: { color: '#fff', fontSize: 25} }}
          rightComponent={{ icon: 'home', color: '#fff' }}
        />
   
        <FlatList 
        ListHeaderComponent={renderHeader}
        keyExtractor={(item) => item.ID.toString() }
        data={fullData}
        renderItem={({item}) => (
          <Card>
            <Card.Title>{item.ID}</Card.Title>
            <Card.Divider/>
            <View style={styles.Container}>
              <Text>{item.Comments}</Text>
              {/* <Image source={require('./System apps/Media Manager/Gallery/AppPhotos/45e5cefd-7798-4fe9-88de-86a0a15b7b9f.jpg')} /> */}
              <Text>{item.RoadName}</Text>
            </View>

            <View style={styles.ListContainer}>
              <Text style={styles.LabelText}>Name</Text>
              <Text style={styles.LabelText}>Phone</Text>
              <Text style={styles.LabelText}>Email</Text>
            </View>
            <View style={styles.ListContainer}>
              <Text style={styles.CardText}>{item.Name}</Text>
              <Text style={styles.CardText}>{item.Phone}</Text>
              <Text style={styles.CardText}>{item.Email}</Text>
            </View>
          </Card>
        )}
        />
     </SafeAreaView>

  );
  } 
}

export default FormsScreen;

I have 2 main problems here.

1.) The tutorial had me initialize data and setData. setData is called and it looks to me like that is the final result after the search. The problem is that the author never actually used the variable data so I what do I do with it? Right now the the list is unaltered no matter what happens.

2.) I know he is using a different API so instead of filtering through First name, Last name, and Email I am only searching through ID. In this section of the tutorial:

const contains = ({ name, email }, query) => {
  const { first, last } = name;

  if (first.includes(query) || last.includes(query) || email.includes(query)) {
    return true;
  }

  return false;
};

How does this code relate first and last to the first and last name values in the data? When I use this code but substitute name with ID and therefor first with id the value of query is correct (19 for example) but the value of ID is 2040 which is not the value I am looking for, but 2040 is the last ID in the database, or in other words the most recently entered row.

This is a sample of my data for reference: data

Any help is greatly appreciated.

Upvotes: 0

Views: 799

Answers (1)

Sameer Kumar Jain
Sameer Kumar Jain

Reputation: 2135

Please update data={fullData} to data={query ? data : fullData} in flat list props. That should display your filtered data whenever search query updated.

Upvotes: 1

Related Questions