await AsyncStorage return a promise instead value - react-native

I have an async function that calls AsyncStorage.getItem but always returns a promise.
I tried to use .then clause but the result is similar
I tried to use AsyncStorage.getItem out of the function but I get the error "await is a reserved word"
getDataStorage = async () => {
console.log("getDataStorage");
var data = '';
try {
data = await AsyncStorage.getItem('dataStorage');
console.log("getting data " + data);
return data;
} catch (error) {
console.log("----" + error.message);
}
};
componentDidMount(){
console.log("componentDidMount");
var data = this.getDataStorage();
console.log(data);
}
The result is first displays the promise then prints the value that I get with getItem().
I want to get the value, I suppose with await the function waits for the result of getItem, is it correct?

Yes, await functions wait for the result. But, in your case its only waiting till returning promise, so you have to change your code as:
componentDidMount = async () => {
console.log("componentDidMount");
data = await this.getDataStorage();
console.log(data);
}

Related

Sequelize, findOrCreate + findAll unexpected behavior

I'm trying to fetch data from a dog API and I want to add to my database only their temperaments. I tried using some loops and a split to isolate the data and then using
findOrCreate() to add only those who are not already in the DB, after that I use findAll()
to get that info from the DB to send it using expressJS.
The unexpected behavior comes when I go to the route that executes all this and the route
only gives about half of the temperaments (they are 124 and it displays arround 54), then when I refresh the page it shows all 124 of them. The DB gets populated with all the 124 in one go so the problem is with findAll()
This is the function that isolates the temperaments and append them to the DB:
module.exports = async () => {
const info = await getAllDogs();
info.forEach(async (element) => {
const { temperament } = element;
if (temperament) {
const eachOne = temperament.split(", ");
for (i in eachOne) {
await Temperament.findOrCreate({
where: { name: eachOne[i] },
});
}
}
});
};
And this is the code that gets executed when I hit my expressJS sv to get the info
exports.temperaments = async (req, res) => {
try {
await getTemperaments(); //this function is the above function
} catch (error) {
res.status(500).send("something gone wrong", error);
}
const temperamentsDB = await Temperament.findAll();
res.json(temperamentsDB);
};
So as you can see the last function executes the function that appends all the data to the DB and then sends it with findAll and res.json()
forEach is a synchronous method so it doesn't await a result of the async callback. You need to do for of in order to get wait for all results:
module.exports = async () => {
const info = await getAllDogs();
for (element of info) {
const { temperament } = element;
if (temperament) {
const eachOne = temperament.split(", ");
for (i in eachOne) {
await Temperament.findOrCreate({
where: { name: eachOne[i] },
});
}
}
}
};

How do get value from async function without then()

I know I have to use then() or in a async function to use await to get the value from other async function .
but how to I get value directly ?
I try to pass the value in normal function but not work .
there is no other way to get the value directly ?
thanks
here is ample :
load_data_normal(key){
this.load_data(key).then((ret_val)=>{
console.log(ret_val);
return ret_val;
})
}
load_data = async (key) => {
const MMM = await AsyncStorage.getItem(key);
return MMM;
}
load_data function just work with then(), but load_data_normal not work ,
I just want to get value from get_data without then ..
The simple solution is just adding async to your load_data_normal, if you want to know more read this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
load_data_normal = async (key) => {
const ret_val = await this.load_data(key);
return ret_val;
}
load_data = async (key) => {
const MMM = await AsyncStorage.getItem(key);
return MMM;
}
Normal function doesn't work with await. You need an async function.
const asynFunction = async() => {
const results = await fetch(url);
console.log('results', results)
}
If you don't want to use async, you need to create a new promise.
const load_data_normal = (key) => {
localStorage.setItem("abc", "somevalue in abc");
load_data(key).then((resuls) => {
console.log("abc", resuls);
});
};
const load_data = (someKey) => {
return new Promise((resolve) => resolve(localStorage.getItem(someKey)));
};
load_data_normal("abc");
Sandbox

async function returns promise instead of array

I've been looking for answers on stack overflow but so far nothing is working.
I'm using this function(below) to retrieve a simple array since i want to show its contents in the return() function.
_retrieveData = async () => {
try {
const value = await AsyncStorage.getItem('FavouritesArray');
if (value !== null) {
// We have data!!
console.log(value);
}
} catch (error) {
// Error retrieving data
}
};
The code does work and it logs the array I want (["Rose","Mojito"]) but i can't figure out how to get the array outside the _retrieveData() function. I've tried returning it (returns a promise) as well as putting it in a global variable and then returning it, but that also just return a promise object.
How do I extract the populated array from this async function?
You can store and retrieve your data like this with AsyncStorage:
const storeData = async (key, value) => {
try {
await AsyncStorage.setItem(key, value);
} catch (error) {
console.log(error);
}
};
const getData = async key => {
try {
const data = await AsyncStorage.getItem(key);
if (data !== null) {
console.log(data);
return data;
}
} catch (error) {
console.log(error);
}
};
then call getData with the key name like you stored your array wherever you want and set the key to a state array.
await getData("yourarraykey")
.then((data) => data)
.then((value) => this.setState({ yourarraystate: value }))
.catch((err) => console.log("AsyncStorageErr: " + err));
after that in this.state.yourarraystate the value of your fetched array will be available.
~Faded

Jest: ReferenceError: Request is not defined

I can't get my jest test to pass even though the code works:
describe("Testing the API call", () => {
test("Testing the API call", () => {
sendToServer("Hey there!")
})
})
And jest throws me this:
ReferenceError: Request is not defined (it can't find Request constructor)
I'm pretty new to jest so I have only tried what I could find on stack overflow, but there are no solutions to this one. I tried to import Request from html and it didn't work.
It would be easier to help you if you would share your getData function, but let me assume that you are doing something like, for fetching your data:
async function getUsers() {
const URL = `https://randomuser.me/api/?results=10`;
try {
const response = await fetch(URL);
return response.json();
}
catch (e) {
console.log(e);
return {}
}
}
The above function will make a call to the Random User API and return an Object with an array of results, in our case 10 random users.
In order to test this function, you can write tests, such as:
describe('getUsers function', () => {
test('the data returned is an object', async () => {
const data = await index.getUsers();
expect(data).toBeInstanceOf(Object);
});
test('the Results array has 10 entries', async () => {
const data = await index.getUsers();
expect(data.results.length).toBe(10)
});
});
Here you will assert, that you do return Object from the call and that you do return correct number of users on call.

How to get AsyncStorage value from outside of function

I want to access my token from ACCESS_TOKEN . and merge to my URL.
async getToken(){
try{
var token = await AsyncStorage.getItem('ACCESS_TOKEN')
}catch(error){}
return token;
};
componentDidMount(){
var v = this.getToken()
Alert.alert(v)
return fetch('http://localhost/'+v);
}
I get the error in the output.
com.facebook.react.bridge.ReadableNativeMap cannot be casst to java.lang.string
You need the async and await in componentDidMount as well as getToken returns a promise (as with all functions declare with async).
async componentDidMount() {
let v = await this.getToken();