React Native: API is not calling on 2nd time(fetch/axios) - react-native

I am creating react-native app using fetch method to get the data from API but when I am build the app(remove and install new app) that time it is calling API called but on 2nd time it is not.
I have also uses
componentDidMount, componentWillMount
but not work for me. following is my code:
export default test extends Component{
_isMounted = false;
constructor(props){
super(props);
this.state = {
showList:[]
}
}
componentDidMount() {
let currentComponent = this;
currentComponent._isMounted = true;
fetch(API_URL, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
}
}).then((response) => { return response.json()})
.then((responseJson) => {
console.warn("responseJson: ", responseJson);
if(currentComponent._isMounted){
currentComponent.setState({showList: responseJson.data});
}
})
.catch((error) => {
console.error(error);
});
}
componentWillUnmount(){
this._isMounted = false
}
}
I have add full code here. this is only called on first time, after that it will get only from cache(I think).Please help me.
Thanks

I'd look into the onEnter hook on your scene using react-native-router-flux.
Something like this should work:
class Test extends Component {
static onEnter() {
fetch(API_URL, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
}
}).then((response) => { return response.json()})
.then((responseJson) => {
console.warn("responseJson: ", responseJson)
if (currentComponent._isMounted) {
currentComponent.setState({ showList: responseJson.data })
}
})
.catch((error) => {
console.error(error)
})
}
}
(if you need to access this in the method, here is an idea)

Related

How do I use Async Storage to save Data Locally after calling fetch in react native?

I want to use Async storage. Each time I call without the async function like this
FunctionLogin = () =>{ //other methods here ........ }
and this does not have await anywhere, it saves to the database but when i use let email = AsyncStorage.getItem('email'); to call it back, it does not return anything like the email just [Object object] is what i see
how do I resolve this
the fetch method to save to async storage looks like this
`FunctionLogin = async () =>{
//navigation.replace('VirtualAccountPage');
let item = {email, password,phone};
fetch('https://xxxxxxxxxxxxxxxx/api/sign-up', {
method: 'POST',
mode: 'cors',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify(item),
})
.then(response => response.json())
.then(responseJson =>{
if (responseJson.message === 'User created Successfully') {
await AsyncStorage.setItem('email', email);
await AsyncStorage.setItem('phone', phone);
alert('I am Registered');
navigation.replace('VirtualAccountPage');
} else {
alert(responseJson);
}
})
.catch(error => {
console.error(error);
});
}`
the function to call it back, so it can be used as persistence looks thus
` FunctionUserDetails = () => {
let email = AsyncStorage.getItem('email');
let phone = AsyncStorage.getItem('telephone');
//navigation.replace('Dashboard');
alert(email);
};`
How do i get this to work?
I want to be able to save data locally using async storage so i can be able to persist the data on some other screens etc. I tried several things to see if It could work as expected, i do not get to see it work as i want.
to get the value from AsyncStorage you need to use await and the function should start with async
fetch('https://xxxxxxxxxxxxxxxx/api/sign-up', {
method: 'POST',
mode: 'cors',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify(item),
})
.then(response => response.json())
.then(async (responseJson) =>{ // add async here
if (responseJson.message === 'User created Successfully') {
await AsyncStorage.setItem('email', email);
await AsyncStorage.setItem('phone', phone);
alert('I am Registered');
navigation.replace('VirtualAccountPage');
} else {
alert(responseJson);
}
})
.catch(error => {
console.error(error);
});
const FunctionUserDetails = async () => { // change this
let email = await AsyncStorage.getItem('email'); // change this
let phone = await AsyncStorage.getItem('telephone'); // change this
//navigation.replace('Dashboard');
alert(email);
};`
Install this updated async-storage npm
Try implementing using below code:
fetch('https://xxxx/login', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify(item),
})
.then(response => response.json())
.then(async (responseJson) =>{ // add async here
if (responseJson.stausCode === 200) {
await AsyncStorage.setItem('name', name);
} else {
alert(responseJson);
}
})
.catch(error => {
console.error(error);
});

React Native: setState doesn't work when calling try-catch function

I tried to call APP with this code imported from another file and it worked fine:
import FormData from 'FormData';
import AsyncStorage from '#react-native-community/async-storage';
let formData = new FormData();
formData.append('userId', '1'); // < this is what I want to change
formData.append('key', '***'); //my key
export function getScoreFromAPI () {
return fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
method : 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body : formData
} )
.then((response) => {
return response.json()
})
.catch((error) => console.log("l'erreure est: " + error))
}
but now I want to change my userId from 1 to an constante from Asyncstorage, so I decide to change my code to this:
constructor(props) {
super(props)
this.state = { infos: [], userId: '' }
}
componentWillMount() {
this.getScoreFromAPI().then(data => {
this.setState({ infos: data })
});
console.log(this.state.infos);
AsyncStorage.getItem(USERID_STORED)
.then((data) => {
if (data) {
this.setState({userId:data})
}
});
}
async getScoreFromAPI() {
let formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //my key
try {
let response = await fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php',{
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
let res = await response.json();
} catch(error) {
console.warn("errors are " + error);
}
};
with a try-catch function but when I call getScoreFromAPI() in ComponentWillMount() I can't setState with received data, I still have an empty array in info:[]
my questions:
how can I replace '1' in userId by a value in asyncstorage in the first file ?
if it isn't possible, what I have do to setState info: [] with my data reveived
I've simplified your code into a promise chain in which calling getScoreFromAPI will execute after getting the userId from AsyncStorage, then storing the response into the infos state, while returning null if there was an error, and logging the error to the console. The data was not previously returned from getScoreFromAPI, so the value would always become null. I have not tested this code, but this should give you a good base to work from:
import FormData from 'FormData';
import AsyncStorage from '#react-native-community/async-storage';
export default class Test {
constructor() {
this.state = {
infos: null,
userId: ''
};
}
componentDidMount() {
AsyncStorage.getItem(this.state.userId)
.then(userID => {
this.setState({ userId: userID || '' });
})
.then(() => {
return this.getScoreFromAPI();
})
.then(data => {
this.setState({ infos: data });
})
.catch(console.error);
}
getScoreFromAPI = () => {
const formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //my key
fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
.then(response => {
// use response data here
return response.json();
})
.catch(e => {
console.error(e);
return null;
});
};
}
You're doing your API call before fetching your value from AsyncStorage (I know this is async but it's not very readable if you do it that way).
getScoreFromAPI doesn't return anything, that's why your setState isn't working.
You don't need to use try and catch here, promises have their own error handling mechanism (the .catch() method).
I think callbacks are more readable and lead to less bugs than using .then() in code.
This is how I would do it:
constructor(props)
{
super(props);
this.state = { infos: [], userId: '' };
this.onSuccess = this.onSuccess.bind(this);
this.onFailure = this.onFailure.bind(this);
}
componentWillMount()
{
// Get userID from local storage, then call your API
AsyncStorage.getItem(YOUR_KEY)
.then(userID=> {
if (userID)
{
this.setState({ userId : userID }, () => {
this.getScoreFromAPI(this.onSuccess, this.onFailure);
});
}
});
}
onSuccess(data)
{
this.setState({
infos : data
});
}
onFailure(err)
{
console.warn('Error ' + err);
}
getScoreFromAPI(onSuccess, onFailure)
{
let formData = new FormData();
formData.append('userId', this.state.userId);
formData.append('key', '***'); //your key
fetch('https://www.globalfidelio.com/gfn_arcol/api/transaction.php', {
method : 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body: formData
})
.then(res => res.json())
.then(json => {
onSuccess(json);
})
.catch(err => {
onFailure(err);
});
}
It's finally done. I tried this and it worked. Thank you to all of you
this is what I have done:
...
const USERID_STORED = "userid_stored";
const GSM_STORED = "gsm_stored";
...
class ScoreList extends React.Component {
constructor(props) {
super(props)
this.state = { infos: [], userId: '', gsmStored: '', }
}
componentWillMount() {
AsyncStorage.getItem(USERID_STORED)
.then(userId => {
this.setState({ userId: userId});
this.getScoreFromAPI(this.state.userId).then(data => {
this.setState({ infos: data });
});
});
AsyncStorage.getItem(GSM_STORED)
.then(gsmStore => {
this.setState({ gsmStored: gsmStore});
});
}
getScoreFromAPI (userId) {
let formData = new FormData();
formData.append('userId', userId);
formData.append('key', '***');
return fetch('https://***',{
method : 'POST',
headers : {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
},
body : formData
} )
.then((response) => {
return response.json()
})
.catch((error) => console.log("l'erreure est: " + error))
};

How to get Html code by fetching web API response?

When we are trying to fetch html code via fetch API response but we are enable to get it because it return "Unexpected Token <"
onLoginService2 = async () => {
try {
var hittingURl = "https://members.iracing.com/membersite/Login?username=dave#rms55.com.au&password=rms55Pa55&utcoffset=-600&todaysdate=1558055491688&checkbox=0";
const myRequest = new Request(hittingURl.toString(),
{
method: 'POST',
headers: {
'Accept': 'text/html',
'Content-Type': 'text/html;charset=ISO-8859-1',
},
timeout: 1000,
// body: JSON.stringify("")
}
);
fetch(myRequest)
.then((response) => console.log("abcdefghijklmon--> "+JSON.stringify(response)))
.then((data) => {
console.log("RESPONSERR----> ",data+"");
// this.setState({ isLoading: false })
// this.onLoginSuccessFull(responseJson)
})
.catch((error) => {
this.setState({ isLoading: false })
console.log("response--31" + error);
})
} catch{
}
// }
}
The response of first then has a method .text(), which return Promise
Try this
fetch(myRequest)
.then(resp => resp.text())
.then(text => {
//text is html
})
*Just copy the above and run in console to see the result.

How to use Promise.All in react-native

I use promise.All to wait finish methods before render component.
I used like this :
constructor(props) {
super(props);
this.controllAll();
}
controllAll() {
Promise.all([this.callFetch()])
.then(([fetchResponse]) => {
console.log('finished', fetchResponse);
})
.catch(err => {
console.log('Mistake:', err);
});
}
callFetch() {
fetch('url', {
method: 'POST',
headers: new Headers({
Accept: 'application/json',
'Content-Type': 'application/json', // <-- Specifying the Content-Type
}),
})
.then((response) => response.text())
.then(leaders => {
this.PutImagesToObject(leaders );
});
}
I want to wait to finish callfetch() method finish before render Component. But when I run, firstly in debug mode I see 'finished'.
Doesnt have to wait to finish CallFetch() method to show me 'finished'
Try to add return statement
callFetch() {
return fetch('url', {
...

await is giving Refrence error in react-native

I have the following code
async _onPress() {
NetInfo.isConnected.fetch().then(isConnected => {
if (isConnected) {
fetch(apiURL + '/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.props.username,
password: this.props.password
})
})
.then((response) => response.json())
.then((responseJson) => {
if (responseJson.status === 'success')
//I am getting error here
await AsyncStorage.setItem('token', responseJson.token);
//moving on to the main screen if server return success
Actions.MainScreen();
} else {
Toast.show({
text: "Wrong username or password!",
type: "danger"
});
}
})
.catch((error) => {
console.log(error);
});
} else {
Toast.show({
text: "Please Connect To Internet",
type: "danger"
});
}
});
}
I am trying to save the token i receive from my API server using AsyncStorage.I get the following errors
Expression statement is not assignmentor call
and RefrenceError:await is not defined
when i try to use await in the location.
But when use the same code at the beginning of the function i get no errors.
I dont know what is wrong. Is it not allowed in async await? I am not too familiar with these.
If _onPress calls some async functions and you want to wait for all of them to finish, you must place an 'await' in front of every single one of them. In addition, every async function, including async callback functions, must be declared async too.
The complete code:
async _onPress() {
**await** NetInfo.isConnected.fetch().then(**async** (isConnected) => {
if (isConnected) {
**await** fetch(apiURL + '/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.props.username,
password: this.props.password
})
})
.then((response) => response.json())
.then(**async** (responseJson) => {
if (responseJson.status === 'success') {
**await** AsyncStorage.setItem('token', responseJson.token);
Actions.MainScreen();
} else {
Toast.show({
text: "Wrong username or password!",
type: "danger"
});
}
})
}
})
}