Unable to return token from AsyncStorage in React Native - authentication

I am using React Native's AsyncStorage to store an authorization token, which will be returned when needed to use for new http requests. While I can successfully store it and console log it, I am having some trouble returning the value. I want to call it in another window, in the fashion of
var x= LocalDb.getAcessToken();
console.log(x);
However it won,t work.
LocalDb.getAccessToken();
This on the other hand, works when getAcessToken() has console.log in it
exports.storeToken=function(token){
AsyncStorage.setItem('access_token', token);
}
^^^^This function successfully saves the token
exports.getAccessToken=function(){
AsyncStorage.getItem('access_token')
.then((value) => {
if(value) {
console.log(value);
**//I want to return the value here, to use in another function**
}
})
.done();
}
I can not return the value when I use the return(value) . How can I return a value from the promise?

You need to return the getAccessToken function with the promise call. I would also return the promise with the value... like this.
exports.getAccessToken=function(){
return AsyncStorage.getItem('access_token')
.then((value) => {
if(value) {
console.log(value);
return value;
}
})
}

Related

ASync/Await is not working as expected in router.BeforeEach guard in vue?

this is my router guard :
router.beforeEach(async (to,from,next)=>{
await store.dispatch('GetPermission');
if(to.matched.some(record => record.meta.requireAuth)){
let permissions=store.state.permissions; //getting empty
console.log(permissions);
if(permissions.filter(per => (per.name === 'read_list').length!=0)){
next({
path:'/dashboard/create'
})
}
else{
next()
}
}
// else if(to.matched.some(record => record.meta.requireAuth)){
// if(store.token!=null){
// next({
// path:'/dashboard'
// })
// }
// else{
// next()
// }
// }
else{
next()
}
});
problem is here though i m using await in dispatch method , i m not getting state value of permissions which is initially empty
here is vuex store code :
GetPermission(context){
axios.defaults.headers.common['Authorization']='Bearer ' + context.state.token
axios.get('http://127.0.0.1:8000/api/user').then((response)=>{
console.log(response)
context.commit('Permissions',response.data.permission)
})
//mutation:
Permissions(state,payload){
state.permissions=payload
}
//state
state:{
error:'',
token:localStorage.getItem('token') || null,
permissions:'',
success:'',
isLoggedin:'',
LoggedUser:{}
}
help me to solve it please ??
actions in Vuex are asynchronous. The only way to let the calling function (initiator of action) to know that an action is complete - is by returning a Promise and resolving it later.
Here is an example: myAction returns a Promise, makes a http call and resolves or rejects the Promise later - all asynchronously
actions: {
myAction(context, data) {
return new Promise((resolve, reject) => {
// Do something here... lets say, a http call using vue-resource
this.$http("/api/something").then(response => {
// http success, call the mutator and change something in state
resolve(response); // Let the calling function know that http is done. You may send some data back
}, error => {
// http failed, let the calling function know that action did not work out
reject(error);
})
})
}
}
Now, when your Vue component initiates myAction, it will get this Promise object and can know whether it succeeded or not. Here is some sample code for the Vue component:
export default {
mounted: function() {
// This component just got created. Lets fetch some data here using an action
this.$store.dispatch("myAction").then(response => {
console.log("Got some data, now lets show something in this component")
}, error => {
console.error("Got nothing from server. Prompt user to check internet connection and try again")
})
}
}
Also,you are calling same route when no permission match, in that case it always call your same route and make infinite loop.
Redirect to access denied page if permission denied.

The user object is empty in app even though it is returned from backend server

Here is an _onPress in my react native app. The purpose of this function is to retrieve the user object and pass it to the next component after the user clicks an item. async/await is used for the db retrieval in _getUser. I can see the user object on the server but myself receives nothing and is empty. I am not sure why the myself is empty. Should _getUser be called in the constructor instead?
async _onPress(id) {
let myself = await _getUser();
if (!myself) console.log("_getUser return nothing in Chat!");
this.props.navigation.navigate("Chat", {eventId: id, user: myself});
}
As _getUser() is returning promise and probably _onPress is getting called directly from ToucableOpacity or some touch responder button, you can resolve promise and then take necessary action like:
_onPress(id) {
_getUser()
.then((data) => {
if (!data) {
console.log("_getUser return nothing in Chat!");
return
}
this.props.navigation.navigate("Chat", { eventId: id, user: data });
})
.catch(err => { console.log(err) })
}

Why AsyncStorage getItem is returning null?

export const USER_KEY = "isLoggedIn";
export const phoneVerified = () => AsyncStorage.setItem(USER_KEY, 1);
export const userInfoVerified = () => AsyncStorage.setItem(USER_KEY, 2);
I have used the above functions to store the value and the below one to get the value.
export const isSignedIn = () => {
return new Promise((resolve, reject) => {
AsyncStorage.getItem(USER_KEY)
.then(res => {
console.log("from isSignedIn : "+res); //res is showing null.
if (res !== null) {
resolve(res);
} else {
resolve(0);
}
})
.catch(err => reject(err));
});
};
Why this always returns null? I was trying async/await but still getting null. I think somehow the data is not storing.
I'm afraid you can only store strings. Please refer to this React Native AsyncStorage storing values other than strings and this https://facebook.github.io/react-native/docs/asyncstorage.html#setitem
Thanks.
As answered by #Vishu Bhardwaj AsyncStorage accepts only string. So you can use JSON.stringify() and JSON.parse() in such cases.
I was stuck with this stupid problem for almost one week, no other way that is suggested in all communities worked for me, but then I found something that is built of react-native which its setState() callback function: https://medium.learnreact.com/setstate-takes-a-callback-1f71ad5d2296.
so the only way that I guarantee that it's the only secure way so far is this that u use the setState() function in your promise and everything that you need to run, put them on a function and call it for the setState() callback function , this is only way you can make sure yourself that you neither get null nor never calling the function . Here I'm going to provide an example of it which this.tokeToServer() is my function which it's used as a callback function.
try {
AsyncStorage.getItem('firebase_token',(err,item) => {
if (item) {
this.setState({
firebase_token: item,
}),this.tokenToServer();
}
});
} catch (error) {
console.log("Error retrieving data" + error);
}
As presented by friend Abdu4, I had the same problem for 4 days and searching for different sites and forums. Attempts with async/await and others, even though you should use these options, the one you completed and really worked was to assign the value through setState by callback
try {
AsyncStorage.getItem('TOKEN_KEY',(err,item) => {
if (item) {
setToken({
Token: item,
});
}
});
} catch (error) {
console.log("Error retrieving data" + error);
}

Execute custom functions one after another - Callback logic in Vue.js

There is a form which submits some data to an API in my component. Assume that it's method is ProcessLogin(). Inside this function I have written my API calls using axios. With the help of then() I have handled my server response and displayed my toast. All good.
Now as a part of my code clean up, I have decided to move all my axios functions to another api.js file and export functions from there. Here is an example function I have in my api.js file :
function ApiLogin(data) {
const url = `${BASE_URL}/authenticate`;
axios.post(url,data).then(response => {
return response;
}).catch(error => {
return error.response;
});
}
On the other side in my component I have my method defined as below :
methods: {
ProcessLogin() {
var status = ApiLogin(this.data);
console.log(status);
}
}
When executing this, I get undefined on my console. I know why it is happening. Because console.log(status) executes before ApiLogin could process and sends it's response. How to handle this kind of situation.? I know that callback is the rescue here, but I am not really sure about how to integrate it.
If you return the axios call from your ApiLogin function:
function ApiLogin(data) {
const url = `${BASE_URL}/authenticate`
return axios.post(url, data)
}
You could then handle the response in your component using then and console log from there:
methods: {
ProcessLogin() {
ApiLogin(this.data)
.then(res => console.log(res))
.catch(err => console.log(err))
}
}
...or with async/await:
methods: {
ProcessLogin: async function() {
try {
var status = await ApiLogin(this.data)
console.log(status)
}
catch(err) {
console.log(err)
}
}
}

React Native AsyncStorage: Accessing Value from Promise Object

When I use AsyncStorage.getItem() to retrieve the value (an email address) of a specified key, it returns a Promise object as indicated in the documentation. The value appears in object like so:
{
_45: 0
_54: null
_65: "testuser#test.com"
_81: 1
}
Can I reliably access this value by calling obj._65 or is there another way to accomplish this?
AsyncStorage return a promise. you can use .then for get value
exemple:
AsyncStorage.getItem('key').then((keyValue) => {
console.log(keyValue) //Display key value
}, (error) => {
console.log(error) //Display error
});
Looking at the docs you should be able to do this reliably to retrieve data from your async storage object.:
try {
const value = await AsyncStorage.getItem('#MySuperStore:key');
if (value !== null){
// We have data!!
console.log(value._65);
}
} catch (error) {
// Error retrieving data
}
you must use this within a function that is async however or you will get a runtime exception.