Storing the access token and the status response in React Native - api

So I am trying to get the status of the response and check if it was 200 and then I want to store the access token in a global variable.
.then((response) => response.json())
.then((responsejson) => {
alert(responsejson.access_token);
console.log(response.text());
})
In the above sample code I can access the access_token , but if I want the response.status so I can check its value I get undefined, so how can I get access for this two value without getting undefined?
.then((response) => {
console.log(text2);
if (response.status == 200) {
}
Here I can get the response.status and the access_token will be undefined.

Have you tried to parse the response into json format after the status checking ?
.then((response) => {
if (response.status == 200) {
response.json().then((responsejson) => {
alert(responsejson.access_token);
})
});
If you have acces to the status in the second block and to the token on the first block, why don't you just mix both of them ?

Related

response of axios retry in main.js in vue js

I have a method named getUsers and it is in created hook in Users Component and I have access token and refresh token in my local storage.
I want that when my token expires, I use refresh token and get new access token and retry last request that was failed because of expired access token.
My problem is I want get response of second try of axios call in first axios call point (in Users component in created hook) because I fill table from response of it.
How can I do that?
main.js:
axios.interceptors.request.use((config) => {
config.headers['Content-Type'] = `application/json`;
config.headers['Accept'] = `application/json`;
config.headers['Authorization'] = `Bearer ${localStorage.getItem('access_token')}`;
return config;
}, (err) => {
return Promise.reject(err);
});
let getRefreshError = false
axios.interceptors.response.use((response) => {
return response
},
(error) => {
const originalRequest = error.config;
if (!getRefreshError && error.response.status === 401) {
axios.post(process.env.VUE_APP_BASE_URL + process.env.VUE_APP_REFRESH_TOKEN,
{refresh_token: localStorage.getItem("refresh_token")})
.then(res => {
localStorage.setItem("access_token", res.data.result.access_token);
localStorage.setItem("refresh_token", res.data.result.refresh_token);
originalRequest.headers['Authorization'] = localStorage.getItem("access_token");
return axios(originalRequest)
.then((res) => {
return Promise.resolve(res);
}, (err) => {
return Promise.reject(err);
});
}).catch(error => {
getRefreshError = true;
router.push('/pages/login')
return Promise.reject(error);
})
}
return Promise.reject(error);
});
Users:
created() {
this.getUsers();
}
You can return a new Promise from error handler of response interceptor. Refresh token there, perform the original request and resolve promise based on the result of actions (refreshing and re-fetching). Here is a general sketch of what you should do.
axios.interceptors.response.use(
(res => res),
(err => {
return new Promise(resolve, reject) => {
// refresh token
// then save the token
// then reperform original request
// and resolve with the response of the original request.
resolve(resOfSecondRequest)
// in case of any error, reject with the error
// and catch it where original call was performed just like the normal flow
reject(errOfSecondRequest)
}
})
)

Login With React Native using Asyncronous storage

I am implementing login in React Native using Asynchronous storage. Here, when users login successfully, i keep the user object in the Asynchronous storage then i access this information to get the Authentication Key for my API request anytime I want to do a request.
When I login and information is stored in the Asynchronous storage, the current app session fails to get the just stored information hence all my authenticated request fails in this session. When I close the app and restart, I can successfully get the information from the Async storage stored in the previous session and make successful authenticated request.
I do not know what I am missing out in my code as I believe I need to refresh or reload the app internally after a successful login but I do not know how to do this in React Native. Any information or help is needed. Here is my Login code.
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
AsyncStorage.setItem(USER_DATA, JSON.stringify(data)).then(val => {
console.log('just before reload in login')
Actions.menu(); //this solves the after login problem as it goes to the next page only after a successful AsyncStorage save
this.setState({ procesing: false });
})
.catch(err => {
this.setState({ procesing: false, error: "Couldn't log you in! Please try again" });
//console.log("\nCouldn't save to AsyncStorage: " + err + "\n");
});
}
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
After I have login, my request looks like ;
//for making a post request
post: (url,body) => {
return fetch(url+'?access-token='+this.state.user.auth_key, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
//'Autorization': 'Bearer token2'
},
})
but the user object is gotten from the Async storage as
getUser(){
return AsyncStorage.getItem("USER_DATA").then(value => {
if(JSON.parse(value) == null) {
return false;
} else {
return JSON.parse(value)
}
});
},
Any Information, Ideas, proposed solutions are highly welcome
If you are receiving the information correctly, you can pass the information to the next screen or use the asynchronous repository as it is now.
If use navigation
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
this.setState({ procesing: false });
this.navigation.navigate("LoginScreen",{data: JSON.stringify(data) })
}
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
LoginScreen
this.state={
data : this.props.navigation.state.params.data
}
If use AsyncStorge
HttpRequest.post('api/login', body)
.then((response) => response.json())
.then((responseJson) => {
if(responseJson.succcode == 201){ //successful login
var data = responseJson.user;
data.loggedIn = true;
AsyncStorage.setItem("USER_DATA", JSON.stringify(data));
this.setState({ procesing: false });
else{
this.setState({ procesing: false, error: "Wrong Username and/or Password! Please try again" });
}
LoginScreen
async componentDidMount() {
let data = await AsyncStorage.getItem("USER_DATA")
}

How to store facebook token in AsyncStorage React Native(Expo)

I am using Expo to Login User with Facebook, I am receiving token with Graph Api but when I try to add the token in Async Storage it is not working.
Please see the code below:
async logIn() {
try {
const {
type,
token,
} = await Facebook.logInWithReadPermissionsAsync('<APP_ID>', {
permissions: ['public_profile'],
});
if (type === 'success') {
// Get the user's name using Facebook's Graph API
fetch(`https://graph.facebook.com/me?access_token=${token}`)
.then((res) => res.json())
.then((tokenKey) => AsyncStorage.setItem('userToken',tokenKey))
.then(() => this.props.navigation.navigate('App'))
} else {
// type === 'cancel'
}
} catch ({ message }) {
alert(`Facebook Login Error: ${message}`);
}
}
I am receiving the token when I console it
fetch(`https://graph.facebook.com/me?access_token=${token}`)
.then((res) => res.json())
.then((tokenKey) => console.log('userToken',tokenKey))
.then(() => this.props.navigation.navigate('App'))
Please help, I am new to react native and asynchronous programming in JavaScript. TIA :)
Try this if you want to get item from AsyncStorage
AsyncStorage.getItem('userToken', (error, result) => {
if (result) {
//result
}
else {
//error
}
});
Are you getting token from AsyncStorage with getItem?
AsyncStorage.getItem('userToken').then((token) => {
this.setState({hasToken: token !== null,localToken : token})
});
Sorry folks the problem was from my side, I was trying to store an object directly into Async Storage, whereas Async Storage only accepts values in String format. I used
.then((tokenKey) => AsyncStorage.setItem('userToken',JSON.stringify(tokenKey)))
and it fixed the problem,Thanks all for your help

when i fetch data from api using for loop i am getting error in react native

async makeRemoteRequestNotification() {
var backapi = api.Backend_API();
let userId = await AsyncStorage.getItem("userid");
fetch(backapi + "event/notification/" + userId, {
method: "GET",
}).then((response) => response.json())
.then((data) => {
for(let i in data){
fetch(backapi+"event/eventname/"+data[i].event_id,{
method:'GET',
}).then((response)=>response.json())
.then((data)=>{
this.state.data.push(data)
console.log("notification event",this.state.data);
})
console.log("created_by",data[i].created_by);
fetch(backapi+"user/getUserById"+data[i].created_by,{
method:'GET'
}).then((response)=>response.json())
.then((data)=>{
console.log("username",data);
})
}
// this.state.data=data;
console.log("clint",this.state.data);
})
};
getting error as
Unhandled Promise Rejection (id: 0): SyntaxError: Unexpected token C
in JSON at position 0
You should check the status of you response before .then((response) => response.json())
For example you can do:
.then((response) => {
if (response.status == 200) {
//Deal with your response and do whatever you want
}
else {
//do somthing with your error status
}
})
Your question is not related to react native. You are getting error when trying to parse an invalid json response (or not json at all). Use debug tools to catch the incorrect server response and use the catch block in promise chain to process such situations.

Aurelia Fetch Client - Stop Chain on Interception

My global configuration in main.js:
http.configure(config => {
config
.withInterceptor({
response(response) {
if (response.status === 500) {
toastr.error('Contact the tech guys.', 'Something has gone wrong!');
throw response;
}
return response;
}
})
.useStandardConfiguration()
.withBaseUrl('api/blah/blah');
In my view models, I also have more handling after using http.fetch(). This is for things like using my validator to wire up error message on fields, etc.
this.http.fetch('some/route',
{
method: 'put',
body: json({some: 'data'})
})
.then(response => response.json())
.then(data => {
this.otherService.doSomeStuff(data);
})
.catch((response) => {
if(response.status !== 500)
response.json()
.then(failures => {
this.validator.handle(failures);
});
});
However, I don't really want to throw response; in my interceptor (I'm doing that now because null was being passed), and, I don't want to do a response.status !== 500 check in each view model.
Is there a way to stop the chain completely with an interceptor?