Home > Software design >  I can't get custom data from API in react native
I can't get custom data from API in react native

Time:08-03

ı am a beginner react native developer. I am trying to GET custom data with changing /name property at the URL. My getData() function is working without problem but when ı use getCustomData() ı am having an error. By the way, ı don't think that ı implemented the API page right. So if you have any suggestions please give me a hand.

If you want to take a look at the repo, The error

This is my main screen to dispaly API data

import {FlatList, StyleSheet, View} from "react-native"
import CountryItem from "../components/CountryItem"
import { useEffect, useState } from "react";
import { getCustomData, getData} from "../util/api";
import SearchBar from "react-native-dynamic-search-bar";



function CountriesOverviewScreen({navigation}){

    const [data, setData] = useState([]);
    const [changedData, setChangedData] = useState('');

    useEffect(()=>{
        getData(setData)
    }, []) 

    useEffect(()=>{
    if (changedData) {
          getCustomData(setData, changedData)
     }
  },[changedData])

    function renderCountryItem(itemData){

        function pressHandler(){
            navigation.navigate('CountriesDetail', {
                name: itemData.item.name,
                flag: itemData.item.flags.png,
                capital: itemData.item.capital,
                population: itemData.item.population,
                timezone: itemData.item.timezones,
                language: itemData.item.languages[0]['name'],
            })
        }
        return (
            <CountryItem
            onPress={pressHandler}
            title={itemData.item.name}
            imageUrl={itemData.item.flags.png}
            />   
        )
    }

    return  (
        <View style={styles.container}>
            <SearchBar
            placeholder="Search here"
            onSearchPress = {(text)=>{setChangedData(text)}}/>
            <FlatList
            style={styles.flatlist} 
            numColumns={2}
            data={data}
            renderItem={renderCountryItem}
            keyExtractor={(item, index) => String(index)}/>
        </View>
    )

}

export default CountriesOverviewScreen

const styles = StyleSheet.create({
    container:{
        marginTop: 15,
    },
    flatlist: {
        margin: 10,
    }
})

This is the api.js

import axios from "axios";

export const getData = async function(setData){
    await axios.get('https://restcountries.com/v2/all')
    .then((json)=> setData(json.data))
    .catch((e)=>{
        console.log(e)
    })
}

export const getCustomData = async function(setData, countryName){
    await axios.get(`https://restcountries.com/v2/name/${countryName}`)
    .then((json)=> setData(json.data))
    .catch((e)=>{
        console.log(e)
    }) 
}

EDIT: ı am getting this after ı console.log(country name) in getCustomData enter image description here

CodePudding user response:

It's a 404 error which means you are accessing the resource which is not available on the server, also in your code there is a " . " missing before then

export const getCustomData = async function(setData, countryName){
await axios.get(`https://restcountries.com/v2/name/${countryName}`)
then((json)=> setData(json))
.catch((e)=>{
    console.log(e)
}) 
}

here add . before then, something like this

export const getCustomData = async function(setData, countryName){
await axios.get(`https://restcountries.com/v2/name/${countryName}`)
.then((json)=> setData(json))
.catch((e)=>{
    console.log(e)
}) 
}

CodePudding user response:

the reason why is that happenning is that you are making an axios get request before the value of the useState has changed as it does not change directly. what you can do instead is:

function CountriesOverviewScreen({navigation}){

    const [data, setData] = useState([]);
    const [changedData, setChangedData] = useState('');
    const [search, setSearch] useState(false);
    useEffect(()=>{
        getData(setData)
    }, []) 

    useEffect(()=>{
    if (search) {
          getCustomData(setData, changedData);
          setSearch(false)
     }
  },[search])

    function renderCountryItem(itemData){

        function pressHandler(){
            navigation.navigate('CountriesDetail', {
                name: itemData.item.name,
                flag: itemData.item.flags.png,
                capital: itemData.item.capital,
                population: itemData.item.population,
                timezone: itemData.item.timezones,
                language: itemData.item.languages[0]['name'],
            })
        }
        return (
            <CountryItem
            onPress={pressHandler}
            title={itemData.item.name}
            imageUrl={itemData.item.flags.png}
            />   
        )
    }

    return  (
        <View style={styles.container}>
            <SearchBar
            placeholder="Search here"
            onSearchPress = {(text)=>{setChangedData(text);setSearch(true)}}/>
            <FlatList
            style={styles.flatlist} 
            numColumns={2}
            data={data}
            renderItem={renderCountryItem}
            keyExtractor={(item, index) => String(index)}/>
        </View>
    )

}

So the changes that I suggested is creating a search state, and it only makes an axios get if the search is true, (the data will be updated by that time as well in the useState)

CodePudding user response:

As you can see in the EDIT block ı logged the countryName and ı found that ı am not returning string, so ı changed the "SearchBar" components function.

onChangeText={(text) => setChangedData(text)}
onSearchPress={() => getCustomData(setData, changedData)}

and also ı take the getCustomData out from useEffect. I am just using it in SearchBar component

  • Related