softare development

Real-time Data Search From API Using Search Bar Filter and ListView in React Native

Real-time data search functionality can be very crucial for your React Native app, especially as it begins to scale.

Let’s picture this:

You have a product listing application with hundreds of available products. It will be incredibly difficult and discouraging for users of your app to begin to sift through the products one-by-one. What if they just want to buy a particular product on the spot?

Implementing the search functionality will make it easier for users to have a good experience with your app and save them quality time that would otherwise be needlessly spent going through a boring cinema of your products. No offence ):

So, let’s begin.

In this tutorial, I’m going to assume that you already have some working knowledge of React Native, which means I’m not going to go through the fundamentals of creating a new React Native application. We have already covered that here.

We shall also, as a matter of necessity, use components from React Native Elements, a library that makes creating UI components seamless. This library also depends on another package called react-native-vector-icons.

Also, we shall be working with GET Request API (Application Programming Interface) that list out names by nationality

We are going to add both dependencies to our React Native application as follows:

npm install react-native-vector-icons

//or

yarn add react-native-vector-icons


npm install react-native-elements

//or

yarn add react-native-elements

Next, let’s create a new component called Home.js (You can give it any name of your choice)

import React, {Component} from 'react';

class Home extends Component {

}

export default Home;

Next, We’ll add some state variables to our code

class Home extends Component {

constructor(props) {
    super(props);
    this.state = {
      search: '',
      data: [],
      error: null,
      loading: false,
    };
  }

}

export default Home;

Moving on, we are going to write a function that makes the search

search = async () => {
    const url = `https://api.nationalize.io/?name=` + this.state.search;
    this.setState({loading: true});
    fetch(url, {
      method: 'GET',
    })
      .then(res => res.json())
      .then(res => {
        this.setState({
          data: res.country,
          error: res.error || null,
          loading: false,
        });
      })
      .catch(error => {
        this.setState({error, loading: false});
      });
  };

To make it easier for us to display our data retrieved from our GET Request, we shall be making use of Flatlist. Aha!

So, let’s render our data as follows. Also, don’t forget to import Flatlist from react-native

//required imports
import React, {Component} from 'react';
import {
  View,
  FlatList,
  TouchableOpacity,
  ActivityIndicator,
  StatusBar,
} from 'react-native';
import {SearchBar, Button, ListItem} from 'react-native-elements';


renderSearch = () => {
    return this.state.data.map(item => {
      return (
        <View>
          <Text>{item.name}</Text>
        </View>
      );
    });
  };

  renderItem = ({item}) => (
    <TouchableOpacity
      onPress={() =>
        requestAnimationFrame(() =>
          this.props.navigation.navigate('Description', {
            title: item.title,
            imageName: item.image_url,
            synopsis: item.synopsis,
            episodes: item.episodes,
            rated: item.rated,
          }),
        )
      }>
      <ListItem bottomDivider>
        <ListItem.Content>
          <ListItem.Title>{item.title}</ListItem.Title>
          <ListItem.Subtitle
            style={{color: '#000', textTransform: 'uppercase'}}>
            country: {item.country_id}
          </ListItem.Subtitle>
          <ListItem.Subtitle
            style={{color: '#9D7463', textTransform: 'capitalize'}}>
            probability: {item.probability}
          </ListItem.Subtitle>
        </ListItem.Content>
      </ListItem>
    </TouchableOpacity>
  );

Finally, We will render our component as follows:

 render() {
    return (
      <View style={styles.searchContainer}>
        <StatusBar barStyle="light-content" backgroundColor={primaryColor} />
        <View style={styles.search}>
          <SearchBar
            containerStyle={{width: '70%', height: 80, backgroundColor: '#fff'}}
            placeholder="Search name"
            lightTheme
            platform="ios"
            autoFocus={true}
            showLoading={false}
            autoCorrect={false}
            value={this.state.search}
            onChangeText={search => this.setState({search})}
          />
          <Button
            buttonStyle={{backgroundColor: primaryColor, padding: 9}}
            title="search"
            onPress={() => this.search()}
          />
        </View>

        {this.state.loading ? (
          <ActivityIndicator
            style={{
              position: 'absolute',
              flexDirection: 'row',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              marginTop: 0,
            }}
            size="large"
            color="#0275d8"
          />
        ) : (
          <FlatList
            style={{flex: 1}}
            data={this.state.data}
            renderItem={this.renderItem}
            keyExtractor={item => item.country_id.toString()}
            ItemSeparatorComponent={this.renderSeparator}
            ListHeaderComponent={this.renderHeader}
          />
        )}
      </View>
    );
  }

Here is our full working code:

import React, {Component} from 'react';
import {
  View,
  FlatList,
  TouchableOpacity,
  ActivityIndicator,
  StatusBar,
} from 'react-native';
import {SearchBar, Button, ListItem} from 'react-native-elements';
import {styles, primaryColor} from '../assets/styles/Style';

class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
      search: '',
      data: [],
      error: null,
      loading: false,
    };
  }

  search = async () => {
    const url = `https://api.nationalize.io/?name=` + this.state.search;
    this.setState({loading: true});
    fetch(url, {
      method: 'GET',
    })
      .then(res => res.json())
      .then(res => {
        this.setState({
          data: res.country,
          error: res.error || null,
          loading: false,
        });
      })
      .catch(error => {
        this.setState({error, loading: false});
      });
  };

  renderSearch = () => {
    return this.state.data.map(item => {
      return (
        <View>
          <Text>{item.name}</Text>
        </View>
      );
    });
  };

  renderItem = ({item}) => (
    <TouchableOpacity
      onPress={() =>
        requestAnimationFrame(() =>
          this.props.navigation.navigate('Description', {
            title: item.title,
            imageName: item.image_url,
            synopsis: item.synopsis,
            episodes: item.episodes,
            rated: item.rated,
          }),
        )
      }>
      <ListItem bottomDivider>
        <ListItem.Content>
          <ListItem.Title>{item.title}</ListItem.Title>
          <ListItem.Subtitle
            style={{color: '#000', textTransform: 'uppercase'}}>
            country: {item.country_id}
          </ListItem.Subtitle>
          <ListItem.Subtitle
            style={{color: '#9D7463', textTransform: 'capitalize'}}>
            probability: {item.probability}
          </ListItem.Subtitle>
        </ListItem.Content>
      </ListItem>
    </TouchableOpacity>
  );

  render() {
    return (
      <View style={styles.searchContainer}>
        <StatusBar barStyle="light-content" backgroundColor={primaryColor} />
        <View style={styles.search}>
          <SearchBar
            containerStyle={{width: '70%', height: 80, backgroundColor: '#fff'}}
            placeholder="Search name"
            lightTheme
            platform="ios"
            autoFocus={true}
            showLoading={false}
            autoCorrect={false}
            value={this.state.search}
            onChangeText={search => this.setState({search})}
          />
          <Button
            buttonStyle={{backgroundColor: primaryColor, padding: 9}}
            title="search"
            onPress={() => this.search()}
          />
        </View>

        {this.state.loading ? (
          <ActivityIndicator
            style={{
              position: 'absolute',
              flexDirection: 'row',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              marginTop: 0,
            }}
            size="large"
            color="#0275d8"
          />
        ) : (
          <FlatList
            style={{flex: 1}}
            data={this.state.data}
            renderItem={this.renderItem}
            keyExtractor={item => item.country_id.toString()}
            ItemSeparatorComponent={this.renderSeparator}
            ListHeaderComponent={this.renderHeader}
          />
        )}
      </View>
    );
  }
}

export default Home;

Don’t run the app yet! Let’s add our style sheet, shall we?

Create a folder called assets. Inside the assets folder, create another folder called styles. Now inside the styles folder, create a file called Style.js and add the following code.

Don’t know how to use an external style sheet in React Native? Check it out here

import {StyleSheet} from 'react-native';

const primaryColor = '#6F3A00';
const secondaryColor = '#00689E';
const white = '#FFF';

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  search: {
    flexDirection: 'row',
    justifyContent: 'space-evenly',
    alignItems: 'center',
  },
  searchContainer: {
    flex: 1,
    backgroundColor: '#fff',
  },
});

export {styles, primaryColor, secondaryColor, white};
React Native API Search Functionality

That’s how we implement a react native real time search.

Enjoy this tutorial? Let me know how it’s going in the comments.

Also support us by sharing, liking and following us on our social media platforms.

Leave a Reply

Your email address will not be published.