react-nativeaxioszomato-api

React Native how to fetch data with API URL


I am trying to retrieve data from the Zomato API (https://developers.zomato.com/documentation) and I am attempting to retrieve restaurants from a selected category. This is my first time using APIs so if anybody can walk me through what I am not understanding, or if there is a mistake in my code I would really appreciate it.

Here is my relevant code:

HomeScreen.js

async componentDidMount(){
  this.setState({
    data: await apiCall('')
  })
}

render() {
  return (
    <View>
      <FlatList
        style={{ marginBottom: 80 }}
        keyExtractor={item => item.id}
        data={this.state.data}
        renderItem={({ item }) =>
          <TouchableHighlight onPress={() => this.props.navigation.navigate('CategoryScreen', { category: item.categories.id })}>//the user will tap on the category and the CategoryID will be moved to the next screen
            <Card style={styles.container}>
              <Text style={{ color: '#000', fontWeight: 'bold' }}>{item.categories.name} </Text>
            </Card>
          </TouchableHighlight>}
      />
    </View>
  );
}
}

once the user taps on the category cell within the flat list the project should list out all the restaurants within that category in the next page

CategoryScreen.js

 async componentDidMount(){
  this.setState({
    data: await apiSearch('`{this.props.navigate.category}`')
  })
  console.log(await apiSearch)
}

render(){
  return (
    <FlatList
      style={{ marginBottom: 80 }}
      keyExtractor={item => item.id}
      data={this.state.data}
      renderItem={({ item }) =>
        <Card style={styles.container}>
          <Text style={{ color: '#000', fontWeight: 'bold' }}>{item.restaurants.name} </Text>
        </Card>}
    />
  );
}

Here is the file in which I have all the API call functions

API.js

import axios from 'axios';

export const apiCall = async () => {
  return await axios.request({
    baseURL: "https://developers.zomato.com/api/v2.1/categories?city_id=New%20Jersey%20",
    headers: {
      'user-key': "a31bd76da32396a27b6906bf0ca707a2",
    },
    method: 'get'
  }).then(async (response) => {
    return response.data.categories
  }).catch(err => console.log(err))
}

export const apiSearch = async (id) => {
  return await axios.request({
    baseURL: `https://developers.zomato.com/api/v2.1/search?category=${id}`,
    headers: {
      'user-key': "a31bd76da32396a27b6906bf0ca707a2",
    },
    method: 'get'
  }).then(async (response) => {
    return response.data.restaurants
  }).catch(err => console.log(err))
}

According to the Zomato API documentation says

List of all restaurants categorized under a particular restaurant type can be obtained using /Search API with Category ID as inputs

each category ID is a specific number and goes at the end of the baseURL in the apiSearch const. So what I'm trying to do is add the category ID from the first page to the end of the URL of the second page because that's how I think the restaurants within each category will be displayed. However I'm starting to think that's not entirely correct. I am just genuinely confused about how to work with APIs


Solution

  • Since you are passing selected category id in HomeScreen.js, you can access that value from CategoryScreen.js as below,

    this.props.navigation.navigation.state.params.category
    

    Now you need pass that value to https://developers.zomato.com/api/v2.1/search as a Parameter

    async componentDidMount() {
        let id = this.props.navigation.state.params.category
        let result;
        try {
          result = await axios.request({
            method: 'GET',
            url: `https://developers.zomato.com/api/v2.1/search?category=${id}`,
            headers: {
              'Content-Type': 'application/json',
              'user-key': "a31bd76da32396a27b6906bf0ca707a2",
            },
          })
        } catch (err) {
          err => console.log(err)
        }
        this.setState({
          isLoading: false,
          data: result.data.restaurants
        })
      }
    

    Finally you can show that data inside CategoryScreen.js

    render() {
        return (
          <View>
            {
              this.state.isLoading ?
                <View style={{ flex: 1, padding: 20 }}>
                  <ActivityIndicator />
                </View> :
                (
                  this.state.data.length == 0 ?
                    <View style={{ flex: 1, padding: 20 }}>
                      <Text style={{ color: '#000', fontWeight: 'bold' }}>No restaurants from selected category</Text>
                    </View> :
                    <FlatList
                      style={{ marginBottom: 80 }}
                      keyExtractor={item => item.id}
                      data={this.state.data}
                      renderItem={({ item }) =>
                        <Text style={{ color: '#000', fontWeight: 'bold' }}>{item.restaurant.name} </Text>
                      }
                    />
                )
            }
          </View>
        );
      }