Search code examples
reactjsreact-reduxreact-nativereact-native-flatlist

How to implement search and filter according to user's keyword to display data from a list of objects?


enter image description here

As the title says I want to achieve the following model,I have a local imported json file, and I want user to write on the search bar,according to the text user writes,I want the json to get filtered and show it at the bottom area. My json object:

export const cards = [
    {
        img: 'https://media.emailonacid.com/wp-content/uploads/2019/05/EOA_MediaQueries2019_Blog.jpg',
        author: null,
        description: 'Liked Songs'
    },
    {
        img: 'https://i.scdn.co/image/ab67706c0000da845f2575c6513aa8e264879e7d',
        author: null,
        description: 'Essa Gelada Eu vou beber'
    },
    {
        img: 'https://vintageculture.com/wp-content/uploads/2020/04/Slow-Down-VC-e-Slow-Motion-Remix.jpg',
        author: null,
        description: 'Slow Down (feat. Jhon)'
    },
    {
        img: 'https://i.pinimg.com/474x/18/a3/b2/18a3b25cf87f439a5c0bc0fa7ae0ca54.jpg',
        author: null,
        description: 'Marilia Mendonça'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b273d77d08d4bb06171ce0fe2a0e',
        author: null,
        description: 'Jorge & Mateus'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b2738ddd20bf644f1d50adafad7b',
        author: null,
        description: 'All Around The World'
    },
]

export const recentlys = [
    {
        img: 'https://i.scdn.co/image/ab67616d0000b2738ddd20bf644f1d50adafad7b',
        author: 'R3AB',
        description: 'All Around The World'
    },
    {
        img: 'https://vintageculture.com/wp-content/uploads/2020/04/Slow-Down-VC-e-Slow-Motion-Remix.jpg',
        author: 'Vinatge Culture',
        description: 'Slow Down (feat. Jhon)'
    },
    {
        img: 'https://i.pinimg.com/474x/18/a3/b2/18a3b25cf87f439a5c0bc0fa7ae0ca54.jpg',
        author: 'Marilia Mendonça',
        description: 'Marilia Mendonça'
    },
    {
        img: 'https://i.scdn.co/image/ab67706c0000da845f2575c6513aa8e264879e7d',
        author: 'Jorge & Mateus',
        description: 'Essa Gelada Eu vou beber'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b273d77d08d4bb06171ce0fe2a0e',
        author: 'Jorge & Mateus',
        description: 'Jorge & Mateus'
    },
]

export const playlists = [
    {
        img: 'https://vintageculture.com/wp-content/uploads/2020/04/Slow-Down-VC-e-Slow-Motion-Remix.jpg',
        author: 'Vinatge Culture',
        description: 'Slow Down (feat. Jhon)'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b2738ddd20bf644f1d50adafad7b',
        author: 'R3AB',
        description: 'All Around The World'
    },
    {
        img: 'https://i.scdn.co/image/ab67706c0000da845f2575c6513aa8e264879e7d',
        author: 'Jorge & Mateus',
        description: 'Essa Gelada Eu vou beber'
    },
    {
        img: 'https://i.pinimg.com/474x/18/a3/b2/18a3b25cf87f439a5c0bc0fa7ae0ca54.jpg',
        author: 'Marilia Mendonça',
        description: 'Marilia Mendonça'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b273d77d08d4bb06171ce0fe2a0e',
        author: 'Jorge & Mateus',
        description: 'Jorge & Mateus'
    },
]

export const artists = [
    {
        img: 'https://i.scdn.co/image/ab67706c0000da845f2575c6513aa8e264879e7d',
        author: 'Jorge & Mateus',
        description: 'Essa Gelada Eu vou beber'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b2738ddd20bf644f1d50adafad7b',
        author: 'R3AB',
        description: 'All Around The World'
    },
    {
        img: 'https://vintageculture.com/wp-content/uploads/2020/04/Slow-Down-VC-e-Slow-Motion-Remix.jpg',
        author: 'Vintage Culture',
        description: 'Slow Down (feat. Jhon)'
    },
    {
        img: 'https://i.scdn.co/image/ab67616d0000b273d77d08d4bb06171ce0fe2a0e',
        author: 'Jorge & Mateus',
        description: 'Jorge & Mateus'
    },
    {
        img: 'https://i.pinimg.com/474x/18/a3/b2/18a3b25cf87f439a5c0bc0fa7ae0ca54.jpg',
        author: 'Marilia Mendonça',
        description: 'Marilia Mendonça'
    },
    {
        img: 'https://i.scdn.co/image/1fd90cd274102d458ec3a9243ced32e659738133',
        author: 'Calvin Harris',
        description: 'Your Daily Mix 1'
    },
    {
        img: 'https://i.scdn.co/image/5e79a3aa31ed34c951b607e26c0df690c0118fc8',
        author: 'KVSH',
        description: null
    },
    {
        img: 'https://i1.sndcdn.com/avatars-000494458926-ftqfqe-t500x500.jpg',
        author: 'R3AB',
        description: null
    },
    {
        img: 'https://i.scdn.co/image/82e6e7e4f318d0b2ba80b09d00db2552966f2fdc',
        author: 'Liu',
        description: 'Your Daily Mix 2'
    },
    {
        img: 'https://i.scdn.co/image/ab67706f000000026cac5751f488923a32f4ee79',
        author: 'Martin Garrix',
        description: null
    },
    {
        img: 'https://penews.com.br/wp-content/uploads/2019/10/vintge-e1571597522273.jpg',
        author: 'Vintage Culture',
        description: null
    },
    {
        img: 'https://i.scdn.co/image/339b4f2b8fa072d2130ad69cd603919e6279258e',
        author: 'ALOK',
        description: null
    },
]

below is the exact code that I have written and where I want to implement the function:

import React, {useState} from 'react';
import {
  SafeAreaView,
  ScrollView,
  View,
  Text,
  TextInput,
  StyleSheet,
  Dimensions,
} from 'react-native';
import {TabView, SceneMap} from 'react-native-tab-view';
import Icon from 'react-native-vector-icons/FontAwesome';

import {cards} from '../../Data/Home';

const FirstRoute = () => <View style={[styles.scene]} />;

const SecondRoute = () => <View style={[styles.scene]} />;
const initialLayout = {width: Dimensions.get('window').width};
export default function Search() {
  const [search, setSearch] = useState({});
  const [index, setIndex] = React.useState(0);
  const [tmpCards] = useState(cards);
  const [routes] = React.useState([
    {key: 'first', title: 'Users'},
    {key: 'second', title: 'Videos'},
  ]);

  const renderScene = SceneMap({
    first: FirstRoute,
    second: SecondRoute,
  });

  const filteredData = () => {
    tmpCards.filter((user) => {
      console.log(
        tmpCards.description.toLowerCase().includes(search.toLowerCase()),
      );
    });
  };
  return (
    <SafeAreaView style={{flex: 1, backgroundColor: '#fff'}}>
      <View style={{padding: 10}}>
        <View style={{flexDirection: 'row', backgroundColor: '#D3D3D3'}}>
          <Icon
            name="search"
            size={20}
            style={{marginTop: 12, marginLeft: 5}}
          />

          <TextInput
            placeholder="Search"
            value={search}
            onChangeText={(search) => setSearch(search)}
            style={{marginLeft: 10}}
          />
          {filteredData.map((user, id) => {
            <Text>{tmpCards.description}</Text>;
          })}
        </View>
      </View>
      <TabView
        navigationState={{index, routes}}
        renderScene={renderScene}
        onIndexChange={setIndex}
        initialLayout={initialLayout}
        style={{backgroundColor: '#fff'}}
      />
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  scene: {
    flex: 1,
  },
});

But am getting this error:

 TypeError: undefined is not a function (near '...filteredData.map...')

Any suggestion would be helpful.


Solution

  • You have couple of issue with your code. fitlerdata method is not returning anything also filter function implementation is wrong as per your requirements. I have modified your code a bit. Please try that now.

    import React, { useState } from 'react';
    import {
        SafeAreaView,
        ScrollView,
        View,
        Text,
        TextInput,
        StyleSheet,
        Dimensions,
    } from 'react-native';
    import { TabView, SceneMap } from 'react-native-tab-view';
    import Icon from 'react-native-vector-icons/FontAwesome';
    
    import { cards } from '../../Data/Home';
    
    const FirstRoute = () => <View style={[styles.scene]} />;
    
    const SecondRoute = () => <View style={[styles.scene]} />;
    const initialLayout = { width: Dimensions.get('window').width };
    export default function Search() {
        const [search, setSearch] = useState({});
        const [index, setIndex] = React.useState(0);
        const [tmpCards] = useState(cards);
        const [routes] = React.useState([
            { key: 'first', title: 'Users' },
            { key: 'second', title: 'Videos' },
        ]);
    
        const renderScene = SceneMap({
            first: FirstRoute,
            second: SecondRoute,
        });
    
        const filteredData = () => tmpCards.filter((user) => user.description.toLowerCase().includes(search.toLowerCase()))
       
    
      return (
            <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>
                <View style={{ padding: 10 }}>
                    <View style={{ flexDirection: 'row', backgroundColor: '#D3D3D3' }}>
                        <Icon
                            name="search"
                            size={20}
                            style={{ marginTop: 12, marginLeft: 5 }}
                        />
    
                        <TextInput
                            placeholder="Search"
                            value={search}
                            onChangeText={(search) => setSearch(search)}
                            style={{ marginLeft: 10 }}
                        />
                        {filteredData().map((user, id) =><Text>{user.description}</Text>)}
                    </View>
                </View>
                <TabView
                    navigationState={{ index, routes }}
                    renderScene={renderScene}
                    onIndexChange={setIndex}
                    initialLayout={initialLayout}
                    style={{ backgroundColor: '#fff' }}
                />
            </SafeAreaView>
        );
    }
    const styles = StyleSheet.create({
        scene: {
            flex: 1,
        },
    });