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
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>
);
}