How do I use a variable outside a function in react native? - react-native

I need to use that variable "let result" outside of this function. I need to use that variable inside of another function. How can I get it?
My code looks like this:
method: "GET",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'Authorization': 'Bearer ' + this.state.clientToken,
},
})
.then((response) => response.json())
.then((responseJson) => {
let result= JSON.parse((responseJson.lstsurveyoncode))
let answer = JSON.parse(responseJson.lstsurveyoncode)[0].qoptions
console.log("responsejson",result[1].QUESTIONCODE)
console.log("answerrr",answer);
console.log("data length",result.length);
this.setState({
isLoading:false,
dataresponse:result,
// count:Object.keys(dataresponse).length
},function(){
});

You can create a global variable, and then update it inside your first function and in the second function you check if the variable is defined
let result;
function firstFunction(){
result = 'Your Json Result'
}
function secondFunction(){
if (!result) return;
// Here you can use your variable result
}

You should read about async-await and state managment in react-native.
For quick solution, you should mark your function with async modifier and await for result. Sample code below:
async function yourRequest() {
return new Promise((resolver, rejected) => {
// your async request
})
.then(response => response.json())
.then(responseJson => {
const result = JSON.parse(responseJson.lstsurveyoncode)
const answer = JSON.parse(responseJson.lstsurveyoncode)[0].qoptions
// ...
return {
result: result,
answer: answer,
}
})
}
async function handleResponse() {
const response = await yourRequest()
// and now, you can access to variables declared at `makeRequest` function
console.log(response.result)
console.log(response.answer)
}

Related

Console.log useState causes it to fire multiple times - React Native

I have the following function. If I try to console.log locationData my console gets overflooded because it logs it multiple times.
function GetGoogleData(){
const [locationData,setLocationData] = React.useState(undefined);
let APIURL = `https://maps.googleapis.com/maps/api/place/details/json?placeid=${locationID}&key=xxxxxxxxxxxxxxxxxxxxxxxxxxx`;
let headers = {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
};
fetch(APIURL,{
method: 'POST',
headers: headers,
})
.then((Response)=>Response.json())
.then((Response)=>{
setLocationData(JSON.stringify(Response))
});
console.log(LocationData)
}
Have a try by moving the API call inside the Life Cycle hook useEffect of React.
Ex.
function GetGoogleData(){
const [locationData,setLocationData] = React.useState(undefined);
useEffect(() => {
let APIURL = `https://maps.googleapis.com/maps/api/place/details/json?placeid=${locationID}&key=xxxxxxxxxxxxxxxxxxxxxxxxxxx`;
let headers = {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
};
fetch(APIURL,{
method: 'POST',
headers: headers,
})
.then((Response)=> Response.json())
.then((Response)=>{
setLocationData(JSON.stringify(Response))
});
}, [])
useEffect(() => {
if (locationData) {
console.log('locationData : ', locationData)
}
}, [locationData])
}
The first useEffect will only executed first mount of component and the second useEffect will call every update of the locationData State changes.

How should i use asyncstorage.setItem in this fetch method?

i want to add the async storage method to save my json response,
but i don't know how to add there specifically
i have already tried like this
UserRegisterationFunction = () => {
const { UserName } = this.state;
const { UserEmail } = this.state;
const { UserPassword } = this.state;
fetch('http://192.168.1.7/test/user_registration.php', {
method: 'POST',
headers: {
'Accept' : 'application/json',
'Content-Type' : 'application/json'
},
body: JSON.stringify({
name: UserName,
email: UserEmail,
password: UserPassword
})
}).then((response) => response.json())
.then((responseJson) => {
AsyncStorage.setItem('token', responseJson)
// this._onValueChange(STORAGE_KEY, responseData.id_token),
Alert.alert(responseJson);
}).catch((error) => {
console.log(error)
});
i am getting my alert successfully but i don't know how should i add the responseJson or if i have used it correctly or not
You can use the asynchronous system or save successfully without using it.
To run asynchronously:
.then(async (responseJson) => {
await AsyncStorage.setItem('token', responseJson.id_token);
Alert.alert(responseJson);
}).catch((error) => {
console.log(error)
});
If your responseJson data is this:
Object {
id_token : "myid"
}
Use the getItem function on the following screen to check the value.
async componentDidmount() {
const tokens = await AsyncStorage.getItem('token');
alert(tokens); // You can see 'myid'
}
The JSON response is an object and you can't store the object directly in AsyncStorage. You can only store the object by converting it into a string.
To store the object:
AsyncStorage.setItem('KEY', JSON.stringify(object))
To retrieve the object:
const jsonObjectString = AsyncStorage.getItem('KEY')
const jsonObject = JSON.parse(jsonObjectString)

AccessToken from AsyncStorage + request by axios

While writing the application in the react-native I met with a certain obstacle related to promises, so I have a function that is responsible for the authorized request
export const authorizeRequest = async () => {
const token = await deviceStorage.getItem('accessToken');
return axios.create({
timeout: 2000,
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
}
});
};
in order to get data from it I write code in the style
authorizeRequest().then(a => a.get('http://192.168.0.60:8080/users/echo2/asd')
.then(response => ToastAndroid.show('Response ' + response.data, ToastAndroid.SHORT))
.catch(error => ToastAndroid.show('error ' + JSON.stringify(error), ToastAndroid.LONG)))
Is it possible to avoid the first use of .then when calling authorizeRequest().then(....) so that the query looks like authorizeRequest().get('xxx').then(xxx).catch(xxx)
Thanks!
Why use promise syntax when you are already using async/await syntax to get your value out of the device storage?
You can rewrite your code using async/await which makes it much easier to see what is going on in your code.
export const authorizeRequest = async (url) => {
try {
const token = await deviceStorage.getItem('accessToken');
const a = await axios.create({
timeout: 2000,
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
}
});
const response = a.get(url);
ToastAndroid.show('Response ' + response.data, ToastAndroid.SHORT);
// return response.data // <- you could return something here
} catch (error) {
ToastAndroid.show('error ' + JSON.stringify(error), ToastAndroid.LONG);
}
};
Writing your code in the above way means that you can avoid promise chaining.
You can then use it in the following way:
await authorizeRequest('http://192.168.0.60:8080/users/echo2/asd')
If you want to get a value from the authorizeRequest function you could just return the response.data and you would access it like this:
const data = authorizeRequest('http://192.168.0.60:8080/users/echo2/asd')
Here are some great articles on promises and async/await.
https://medium.com/#bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8
https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9

React Native fetch doesn't work in another fetch callback

If I call my api function from POINT 1, fetch method inside the api method works well. When I comment it out and call the function at POINT 2 fetch method inside the addAccount() doesn't work. There is no exception, no rejection, no request on Reactotron, even I can't find request over Charles Proxy. What is the difference and what I have to know to figure it out?
I tried with RN 0.55.2 and 0.57.5
// Auth.js typical react native component
import * as api from '../actions/api';
class Auth extends Component {
// first triggered function
loginAccount(){
// api.addAccount(); // POINT 1 - this line works well if I uncomment
fetch('https://domain-a.com/login/',{
method: 'POST',
credentials: "same-origin",
headers: {
'accept-language': 'en-US;q=1',
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
body: encodeURIComponent(bodyParameters)
}).then((response) => {
console.log(response);
return response.json()
}).then(({ status, invalid_credentials }) => {
if(status == "ok"){
CookieManager.get('https://domain-a.com')
.then((cookies) => {
this.fetchAccountData(cookies);
})
})
}
fetchAccountData(cookies){
fetch('https://domain-a.com/'+cookies.user_id+'/info/',{
method: 'GET',
headers: {
'cookie': cookies
}
}).then((response) => {
return response.json();
})
.then(({ user, status }) => {
api.addAccount(); // POINT 2 - this line doesn't work
});
}
}
// api.js
// I repleaced fetch code with document example just to be clearify
export const addAccount = () => {
console.log("fetch begin"); // always works
fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson); // won't works from point 2
})
.catch((error) =>{
console.error(error); // never runs
});
}
It looks like your first .then statement in the addAccount() function is missing a return statement. responseJson would be undefined without a proper a 'return response.json()' statement. Also adding brackets for better semantic formatting.
export const addAccount = () => {
console.log("fetch begin"); // always works
fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => {
console.log(response); //test this response
return response.json();
})
.then((responseJson) => {
console.log(responseJson); // won't works from point 2
})
.catch((error) =>{
console.error(error); // never runs
});
}

When to return fetch() and when just using fetch() request?

i'm starting in react native and one thing i've been wondering is that, sometime i see fetch is used like this:
createTodo(){
fetch('http://192.168.1.34:3000/createTodo', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
content: this.state.noteText,
}),
}).then((response) => response.json())
.then((responseJson) => {
var d = new Date();
this.state.noteArray.push({
'date':d.getFullYear()+
"/"+(d.getMonth()+1) +
"/"+ d.getDate(),
'note': responseJson.data.content
});
this.setState({ noteArray: this.state.noteArray });
this.setState({noteText:''});
console.log(responseJson);
}).catch((error) => {
console.error(error);
console.log('Shit! Error occured');
});
}
this work fine.
and sometime it is:
return fetch(...)...
I'm a bit confused.
fetch is Promise which returns another Promise. Resolved results passed to next .then input parameters. So in your example code, you can handle response values which is passed by fetch function.
You can return your fetch function when the client of createTodo wants to use the 'result' of createTodo. The 'result' is another Promise whose input parameters are from createTodo's return values
demo link: https://codesandbox.io/s/548lwxzyn
Demo is just for showing that return value of Promise is another Promise. I hope you can get hint.