React native setState value before fetch - react-native

In react native code, I have a 2 state for example.
const [data, setData] = useState([]);
const [page, setPage] = useState(0);
When call a function, ie search function
search = async() => {
setData([]);
setPage(0);
console.log("Page: " + page); // This will return 0 because of the setPage(0) above, or can call setPage((state)) to wait until page set to 0
}
If multiple time call search function above, the page will be 0. It is expected.
But if this code continue,
search = async() => {
setData([]);
setPage(0);
console.log("Page: " + page); // This page will be always increment because fetch then setPage+1 above
fetch(url)
.then((response) => response.json())
.then((json) => { setData(data.concat(json.content)); setPage(page+1); })
.catch((error) => console.error(error))
.finally(() => { });
}
The log will be
Page: 1
Page: 2
Page: 3
Which the expected should be always Page: 0
The question is, how to set the page become 0, then fetch url so before fetch the value is always 0. The objective is very simple, when this search function triggered, the page must be 0 then fetch the data again.

Since you always want your page to be 0 always before fetch which means setPage(page+1); should make page 1 ,then here is what you can do:
search = async() => {
setData([]);
fetch(url)
.then((response) => response.json())
.then((json) => { setData(data.concat(json.content)); setPage(1); })
.catch((error) => console.error(error))
.finally(() => { });
}
directly assign page to be 1 instead of doing page+1.
EDIT
const[start,setStart]=useState(false);
useEffect(()=>{
if(start){
setPage(0);
setData([]);
}
},[start])
search = async() => {
setStart(true);
console.log("Page: " + page); // This page will be always increment because fetch then setPage+1 above
fetch(url)
.then((response) => response.json())
.then((json) => { setData(data.concat(json.content)); setPage(page+1); })
.catch((error) => console.error(error))
.finally(() => { });
setStart(false);
}

Related

Fecth JSON URL in React Native

I am trying to obtain the data from this website: https://reactnative.dev/movies.json
I use the following code:
fetch("https://reactnative.dev/movies.json")
.then(response => response.json())
.then((responseJson) => {
setTimeout(() => {
this.setState({
loading: false,
dataSource: responseJson
})
}, 2000)
Alert.alert(responseJson)
})
.catch(error => console.log(error))
return (
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={this.onRefresh} tintColor={themes[theme].auxiliaryText} />
}
/>
);
};
My problem is that Alert.alert (responseJson) throws the following error:
This error
... and I would like to get the data for the flatlist.
Who helps me, please?
UPDATE:
...
constructor(props) {
super(props);
this.state = {
moviesList: '',
};
}
...
renderScroll = () => {
const { moviesList } = this.state;
fetch("https://reactnative.dev/movies.json")
.then(response => response.json())
.then((responseJson) => {
setTimeout(() => {
this.setState({
loading: false,
moviesList: responseJson.movies
})
Alert.alert(moviesList)
}, 2000)
})
.catch(error => console.log(error))
...
I would like Alert.alert to receive the data. That is to say, get the data out of the fetch function.
If inside the Alert.alert I put responseJson.movies if the data appears, but if I put moviesList it won't
If I post the following in the browser console it sends me an undefined error. I just want to receive the data from outside the function.
fetch("https://reactnative.dev/movies.json")
.then(response => response.json())
.then((responseJson) => {
setTimeout(() => {
this.setState({
loading: false,
moviesList: responseJson.movies
})
}, 2000)
})
.catch(error => console.log(error))
alert(this.moviesList)
You must print your response data by console.log and make sure what the response data is.
According to your error, I think you are getting Object type data after fetching, but you need to assign String into Alert.alert, therefore I suggest you try the following.
Alert.alert(responseJson.title)
I just tested this code it seems to be working. Is that what you are looking for?
with currElement you have access to the filmed object.
import { useEffect, useState } from "react"
function Home() {
const [isLoading, setLoading] = useState(true)
const [data, saveData] = useState([])
useEffect(() => {
fetch("https://reactnative.dev/movies.json")
.then(response => response.json())
.then(responseJson => {
console.log(responseJson.movies)
saveData(responseJson.movies)
setLoading(false)
})
.catch(error => console.log(error))
}, [])
console.log(data)
return isLoading ? (
<p> i am loading</p>
) : (
<ul>
{data.map(currElement => (
<li key={currElement.id}> {currElement.title}</li>
))}
</ul>
)
}

React Native BackgroundTimer API Fetch respons more than once

I am new on React Native, somethings could be wrong in my code.
I want to check API every 10-sec. The code should be okay but I don't understand why it responds more than once every time when the Backgroundtimer calls.
const App = () => {
const [isLoading, setLoading] = useState(false);
const [data, setData] = useState([]);
useEffect(() => {
fetch('http://192.168.2.131/api/QChatTrakan?templateNo=22')
.then((response) => response.json())
.then((json) => setData(json))
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, [reflesh]);
BackgroundTimer.runBackgroundTimer(() => {
fetch('http://192.168.2.131/api/QChatTrakan?templateNo=22')
.then((response) => response.json())
.then((json) => setData(json))
.catch((error) => {
console.error(error);
});
console.log(data);
},
10000);
enter image description here
You can check the below code for call function or fetch API every 10 seconds.
const callAPi = () => {
console.log('callAPi initial',new Date().toLocaleString())
setInterval(() => {
console.log('callAPi',new Date().toLocaleString())
},10000)}
useEffect(() => {
callAPi()
}, [])

Getting variable from AsyncStorage and putting into Axios

I have been trying to get a variable from AsyncStorage and then put it into an Axios get request. The problem is that the variable is not updating to the data that is retrieved from AsyncStorage. How do I make it do that?
Here is my code:
const [sku, setSku] = useState('')
const STORAGE_KEY_SKU = '#save_sku'
const readSku = async () => {
try {
const selectedSku = await AsyncStorage.getItem(STORAGE_KEY_SKU)
if (selectedSku !== null) {
setSku(selectedSku)
}
} catch (e) {
alert('Failed to fetch the data from storage')
}
}
useEffect(() => {
readSku()
}, []);
useEffect(() => {
Axios.get(`https://api.vexdb.io/v1/get_matches?sku=${sku}`)
.then(({ data }) => {
//console.log("defaultApp -> data", data)
setData(data.result)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}, []);
Im trying to put get the sku variable from the state from AsyncStorage, but the ${sku} in the axios get request link is not working, the sku is blank in that statement.
Please help, thanks!
useFocusEffect(() => {
readSku()
}, []);
const STORAGE_KEY_SKU = '#save_sku'
// to get the session username from localstorage
const readSku = async () => {
try {
const selectedSku = await AsyncStorage.getItem(STORAGE_KEY_SKU)
if (selectedSku !== null) {
setSku(selectedSku)
}
} catch (e) {
console.log(e);
}
}
const setSku = async (selectedSku) => {
Axios.get(`https://api.vexdb.io/v1/get_matches?sku=${selectedSku}`)
.then(({ data }) => {
//console.log("defaultApp -> data", data)
setData(data.result)
})
.catch((error) => console.error(error))
.finally(() => setLoading(false));
}

How to assign value to global variable in fetch method in react native?

I am creating a react native app and I'm getting data from an API. I need to assign specific data into a global variable. That means my API return JSON data like {user_Id:"1' user_name:'abc' user_email:'abc#gmail.con'}. I need to assign user_Id into a global variable to access that in all of my screens.
This is what I tried;
componentDidMount() {
const arrFinal = [];
const {userDel} = this.state;
fetch('my API url')
.then(response => response.json())
.then(responseJson => {
// console.warn(responseJson);
arrFinal.push(responseJson);
arrFinal.map((item, index) => {
global.UserID = item.user_Id
})
.catch(error => {
console.error(error);
});
console.error(global.UserID)
}
But here nothing will print on console. How can I fix this problem?
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
componentDidMount() {
const arrFinal = [];
const {userDel} = this.state;
fetch('my API url')
.then(response => response.json())
.then(responseJson => {
// console.warn(responseJson);
arrFinal.push(responseJson);
arrFinal.map((item, index) => {
global.UserID = item.user_Id
console.error(global.UserID)
})
.catch(error => {
console.error(error);
});
// console.error(global.UserID)
}
or :
async componentDidMount() {
const arrFinal = [];
const { userDel } = this.state;
const response = await fetch('my API url');
const responseJson = await response.json();
// console.warn(responseJson);
arrFinal.push(responseJson);
arrFinal.map((item, index) => {
global.UserID = item.user_Id;
console.error(global.UserID);
});
console.error(global.UserID);
}

React Native, Fetch, and Dispatch: How do I access responseData within mapDispatchToProps()?

I'm fetching JSON Data within componentWillMount() from my "Scanner" component like so:
async componentWillMount() {
const url = 'https://foo.com/products/product1.json';
fetch(url)
.then((response) => response.json())
.then((responseData) => this.props.dispatchProductLoad())
.catch(error => {
console.log(error);
});
}
And below is my dispatch code:
function mapDispatchToProps(dispatch) {
return { dispatchProductLoad: () => dispatch(productLoad(SOMEDATA)) };
};
export default connect(null, mapDispatchToProps)(Scanner);
Where the variable SOMEDATA should hold the value from responseData (at the moment it's not defined)
So my question is - how do I set the value of SOMEDATA to the value held in responseData?
You would call the action creator with the responseData as an argument and define your mapDispatchToProps function like
async componentWillMount() {
const url = 'https://foo.com/products/product1.json';
fetch(url)
.then((response) => response.json())
.then((responseData) => this.props.dispatchProductLoad(responseData))
.catch(error => {
console.log(error);
});
}
function mapDispatchToProps(dispatch) {
return { dispatchProductLoad: (response) => dispatch(productLoad(response)) };
};
export default connect(null, mapDispatchToProps)(Scanner);