I'm trying to fetch data from API, using the link combined from link fetched from another component and API token, but the API is not returning anything.
I suspect the connection to API might be correct and the issue lies with wrongly fetching specific objects from the API structure. api structure
componentDidMount(){
const { navigation } = this.props;
const linkPlant = navigation.getParam('linkPlant');
fetch(linkPlant + '?token=/////FY03yEVzS77Ca1Q9TIbMdMlJhXtpOjhcqcD-MJHA')
.then(response => response.json())
.then((responseJson)=> {
this.setState({
loading: false,
dataSource: responseJson
})
})
.catch(error=>console.log(error))
}
renderItem=(data)=>
<TouchableOpacity style={styles.list}>
<Text style={styles.lightText}>{data.item.varieties[0].common_name}</Text>
</TouchableOpacity>
render(){
return(
<View>
<FlatList
data= {this.state.dataSource}
renderItem= {item=> this.renderItem(item)}
keyExtractor= {item=>item.id.toString()} />
</View>
</ScrollView>
);}
{!loading?
<View>
<FlatList
data= {this.state.dataSource}
renderItem= {item=> this.renderItem(item)}
keyExtractor= {item=>item.id.toString()} />
</View>
: <View><Text>Loading</Text></View>}
You've defined an loading promise but never used that. Maybe using it for render when page is loaded could be fix that error.
Related
I am trying to fetch two different api with axios and use it on different flatlist
I'm getting this error:
[Unhandled promise rejection: Error: Request failed with status code 429]
Possible Unhandled Promise Rejection (id: 28)
Here's the my code
const [data, setData] = React.useState([]);
const [data1, setData1] = React.useState([]);
axios.all([
axios.get('https://jsonplaceholder.typicode.com/nation'),
axios.get('https://jsonplaceholder.typicode.com/state')
])
.then(responseArr => {
setData(responseArr[0].data);
setData1(responseArr[1].data);
});
return (
<View style={styles.container}>
<View >
<FlatList
data={data}
listKey="nation"
keyExtractor={item => item.id}
showsVerticalScrollIndicator = {false}
renderItem={({item}) => {
return (
<View>
<Text>{item.event_id}</Text>
</View>
)
}}
/>
</View>
<View style={{ marginTop: 30 }}>
<FlatList
data={data1}
listKey="state"
keyExtractor={item => item.id}
showsVerticalScrollIndicator = {false}
renderItem={({item}) => {
return (
<View>
<Text>{item.venue_id}</Text>
</View>
)
}}
/>
</View>
</View>
);
};
Thank for your help
You are receiving a HTTP 429 error code which means:
The HTTP 429 Too Many Requests response status code indicates the user has sent too many requests in a given amount of time ("rate limiting").
You are calling the API too many times, what's happening is:
axios is called.
setData() is executed and your state variable updates.
The rerender is causing axios to run again.
Congratulations, you're now in a loop!
Refactor your code to only run the API call at appropriate times. Something like this:
useEffect(() => {
axios.all([
axios.get('https://jsonplaceholder.typicode.com/nation'),
axios.get('https://jsonplaceholder.typicode.com/state')
])
.then(responseArr => {
setData(responseArr[0].data);
setData1(responseArr[1].data);
});
}, []); // Ensure any dependencies are added here.
For good measure you should also handle the rejection, which is what the original error is mentioning.
axios.all().then().catch() - You're missing a catch statement.
For the question in the comments, you need to use back ticks when interpolating strings.
<Image
source={{
uri: `https://jsonplaceholder.typicode.com/nation/image/${item.nation_image}`
}}
/>
i have broken my head trying to understand a problem with my code. I'm new with React Native so there may be a standard behavior that i am unaware of. This is my problem:
In my component i have a useEffect() to load my data like "componentDidMount":
useEffect( () => {
async function loadDadosLista(){
let listaRecebida = await getListaByID(route.params.idLista);
setLista(listaRecebida);
};
loadDadosLista();
}, []);
My function works correctly, the function getListaById accesses my realm.db and return my object lista. After that I can access the data and associate it with components of type TextInput. My real problem is that any change the i do in any component using properties of lista, overwrites all data leaving only the one that has been modified. I'm using spread operator but apparently it doesn't work. Below is my complete code for better understanding.
function ListConfig(){
const [lista, setLista] = useState({});
useEffect( () => {
async function loadDadosLista(){
let listaRecebida = await getListaByID(route.params.idLista);
setLista(listaRecebida);
};
loadDadosLista();
}, []);
return(
<View style={styles.container}>
<View style={[styles.containerLinha, styles.linha2]}>
<View style={styles.inputLocal}>
<TextInput
name='estabelecimento'
placeholder='Venda do seu Francisco'
placeholderTextColor={theme.colors.cinzaPrimario}
style={styles.textInputLocal(theme)}
value={lista.estabelecimento}
maxLength={25}
onChangeText={ (value) => {
setLista({
...lista,
estabelecimento: value
})
}}
textAlignVertical='bottom'
/>
<IconLocation width={20} height={24} />
</View>
</View>
<View style={styles.containerNotif}>
<Text style={styles.textoNotif(theme)}>
Me notifique 20 minutos antes
</Text>
<ToggleSwitch
isOn={lista.notificacaoAtiva}
onColor={theme.colors.cinzaSecundario}
offColor={theme.colors.cinzaSecundario}
thumbOnStyle={{
backgroundColor: theme.colors.destaque
}}
size="medium"
onToggle={(isOn) => {
setLista({
...lista,
notificacaoAtiva: isOn
});
}}
/>
</View>
</View>
);
}
export default ListConfig;
My object lista have this properties:
{
estabelecimento: 'nameOfEstabelecimento',
notificacaoAtiva: true
}
I'm new to react native and my english is so-so and i couldn't find solution to my problem. My goal is to, once fetched a json array, to give the component the onPress navigator function so that, by clicking on the chosen item, it can send me back to a second page with the data of the array value.
export default class Brewery extends React.Component{
state ={
breweries: []
}
async componentDidMount(){
let url='https://jsonplaceholder.typicode.com/photos'
fetch(url)
.then((response) => response.json())
.then((json) =>{
console.log('JSON' , json)
this.setState({breweries: json})
})
.catch((error) => {
console.error(error);
this.setState({breweries:[]})
});
}
render(){
return(
<FlatList
numColumns={2}
data={this.state.breweries}
renderItem={({ item }) => (
<View style={styleSingleResult.box}>
<Image style={styleSingleResult.logo}
source={{uri: item.thumbnailUrl}} />
<Text>{item.title}</Text>
</View>
)}
ListEmptyComponent={() =>
<View>
<Text>NSE Ciae DIOLADRO</Text>
</View>}
/>
)
}
}
I thought I would use
<TouchableOpacity onPress={() => navigation.navigate('NextPage', item)}>
and in the destination page the get:
<Text>{navigation.getParam('title')}</Text>
To recall the value of the item. Except that in the Brewery class I can't implement the "navigation" method .. How can I solve?
I read your requirement, So the solution is create a component name it for example:
<SecondScreen data={breweries} />
And when component mounted you can access data if exists or fetched well from server without any error.
I hope help you with my poor explaining
So I am using react-navigation 5 and I have a custom drawer component for my app. I want to display the name of the logged-in user in the drawer for which I am using a state variable and I am updating the state from firestore. I am calling a function in useEffect which accesses firestore and gets the name of the user. But I think the useEffect is not working without refresh because unless I save the project and refresh the application the state is not getting updated in the application and I cannot see the name of the user without refreshing but it is visible after a refresh. Any ideas why this is happening? Any help would be appreciated. Thank you.
Custom drawer
export default function CustomDrawer(props) {
const paperTheme = useTheme();
const [name,setName]=useState('');
useEffect(() => {
doStuff();
}, []);
const doStuff = async () => {
var phone=global.phone;
await firestore().collection("Users").where('Phone Number', '==', phone).get().then(querySnapshot=>{
querySnapshot.forEach(documentSnapshot => {
console.log("in drawer");
console.log(documentSnapshot.data());
setName(documentSnapshot.data().Name);
})
})
};
return(
<View style={{flex:1}}>
<DrawerContentScrollView {...props}>
<View style={styles.drawerContent}>
<View style={styles.userInfoSection}>
<View style={{flexDirection:'row',marginTop: 15}}>
<Avatar.Image
source={{
uri: ''
}}
size={50}
/>
<View style={{marginLeft:15, flexDirection:'column'}}>
<Title style={styles.title}>{name}</Title>
</View>
</View>
</View>
</View>
</DrawerContentScrollView>
</View>
);
}
Looks like you have doStuff function defined outside the useEffects.
Either you need to put it inside useEffects or add it in dependency list
useEffect(() => {
doStuff();
}, [doStuff]);
I am making a react native app that loads data from google firebase and then display it on a page, when a user clicks on any of the products aa modal will open to show more datails.
I am using useEffect to load the data on page load then display then results:
const fetchData = async () => {
const categories = db.collection("productsDB");
const collections = await categories
.limit(6)
.onSnapshot((querySnapshot) => {
const items = [];
querySnapshot.forEach((documentSnapshot) => {
items.push({
...documentSnapshot.data(),
key: documentSnapshot.id,
});
});
setItems(items);
setLoading(false);
});
return () => collections();
};
useEffect(() => {
fetchData();
}, []);
and the show them like this:
{loading ? (
<ActivityIndicator />
) : (
items.map((item) => (
<TouchableOpacity
style={styles.queryResult}
key={item.key}
onPress={() => {
setModalVisible(!modalVisible);
}}
>
<View style={styles.queryResultContent}>
<Image
style={{ width: 100, height: 100 }}
source={{ uri: String(item.images) }}
/>
<View>
<Text style={styles.queryInfoHeader}>{item.name}</Text>
</View>
</View>
<View>
<ProductModal
isModalVisible={modalVisible}
setModalVisible={setModalVisible}
navigation={navigation}
{...item}
/>
</View>
</TouchableOpacity>
))
)}
when I open the modal, it opens the modal for all of the products and doesnt really matter if I click on the first product or what, it opens all of the modals, and I am not sure how to get rid of this!
is there any better way to write this function?
You're using the same modalVisible flag for all of your modals; therefore, they either are all visible or all hidden.
Why not have a single modal rather than rendering a bunch of them in the loop, and pass the item as a prop to it?