I am using Asyncstorage to store user data like:
try {
await AsyncStorage.setItem(prod_id, '1').then(()=>{
alert('Added to Cart');
});
} catch (error) {
console.log(error);
}
but when I add it to onPress action it takes long time to save data and then my alert is called. Am I doing something wrong? Please I need help!
I think you are mixing two ways of handling the promises in JS.
Using Async await
async function SetItem(){
try {
await AsyncStorage.setItem(prod_id, '1')
alert('Added to Cart');
} catch (error) {
console.log(error);
}
}
with then and catch
function SetItem(){
return AsyncStorage.setItem(prod_id, '1')
.then(()=>{
alert('Added to Cart');
}).catch((error)=> {
console.log(error)
})
}
calling this method
this.SetItem().then(()=>{
console.log("value is set");
})
Related
So I implemented this code in a file from the react native docs.
class Storage {
//store data in 'key'
store = async (key, data) => {
try {
await AsyncStorage.setItem(key, data);
} catch (error) {
// Error saving data
console.log(error.message);
}
};
retrieve = async (key) => {
try {
const value = await AsyncStorage.getItem(key);
if (value !== null) {
// We have data!!
console.log(value);
}
} catch (error) {
// Error retrieving data
console.log(error.message);
}
};
}
And this in other I want to use to actually store and retrieve the variables:
strg.store('test', 'testing');
testing = strg.retrieve('test');
I kept getting an error but then looking it up here I figured out my storage output was an object and not a string as I expected. So I used JSON.stringify(***) and this gibberish came out instead of a "testing".
{"_40":0, "_65":0, "_55":null,"_72":null}
edit: I figure out how to use the console to debug and I found out the 'testing' was inside the promise object that comes out of my function. I read a little about async functions and now I want to know how do I extract the values from the promises?
This happened because you are using AsyncStorage - an asynchronous storage system. You have to wait until it done retrieve data from storage to get the proper data.
I think there are two correct ways to get data from your implementation:
Use async with your container function name & await with your function called
async function getData() {
....
let data = await strg.retrieve('test');
console.log("data", data);
}
or simple use .then():
strg.retrieve('test').then((data) => {
console.log("data", data);
// Handle retrieved data
});
Hope that help. :)
This is how i did it and it works like a charm
import { AsyncStorage } from 'react-native';
module.exports = {
retrieve: async (value) => {
try {
let data = await AsyncStorage.getItem(value);
return data;
} catch (err) {
return err;
}
},
store: async (key, value) => {
try {
// stringify the value since value can only be string.
if (typeof (value) === 'object')
value = JSON.stringify(value)
return await AsyncStorage.setItem(key, value);
} catch (err) {
console.log(err)
return err;
}
}
}
Your store and retrieve functions are asyn so you have to use await until the actual task is complete.
So the code should be like below.
await strg.store('test', 'testing');
const testing = await strg.retrieve('test');
The garbage value is a promise so it will be something like the object you got.
If you return value like this you will retrieve it from outside.
const value = await AsyncStorage.getItem(key);
if (value !== null) {
// We have data!!
console.log(value);
return value;
}
I'm trying to store my users authorization key using AsyncStorage but whenever I do I get weird characters. Here is my relevant code:
async function retrieveItem(key) {
try {
let retrievedItem = await AsyncStorage.getItem(key).then(value => retrieveItem = value);
return retrievedItem;
} catch (error) {
console.log(error.message);
}
return
}
let test = retrieveItem('#authentication')
class AppNavigation extends Component {
render() {
console.log(test)
...
This is the output that I get for test. The item that I want is there under _55 and I'm able to get it by doing console.log(test._55). I just wanted to make sure I am not doing this correctly. Will the key always be _55 for async storage?
{"_40": 0, "_55": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1ZTk1ODM3NDJlZDI1YjAxMWM4MWFiNWEiLCJpYXQiOjE1ODY4NTY4MjB9.yK0WYuZj7_2Nih7phisi5rmm0y7gF__PMRMEAafIkFk", "_65": 1, "_72": null}
You should note use async/await and .then together, both do the same thing.
Try this code instead:
async function retrieveItem(key) {
try {
let retrievedItem = await AsyncStorage.getItem(key);
return retrievedItem;
} catch (error) {
console.log(error.message);
}
return
}
let test = await retrieveItem('#authentication')
class AppNavigation extends Component {
render() {
console.log(test)
Edit: the object you got is a promise and you can get its value by doing the async/await syntax or calling .then(...)
its actually Promise Pointer you have to resolve the Promise by await
use it in classes
async componentDidMount() {
let test =await retrieveItem('#authentication');
console.log(test);
}
use it in hooks
useEffect(async () => {
let test =await retrieveItem('#authentication');
console.log(test);
});
I am a beginner at react-native.
I trying to retrieve data that stored from screen1.js in Screen2.js but I failed.
I have import Asyncstorage from react-native for both .js
This how I store variable from screenone.js :
class screenone extends Component {
state = {
oldpin: '000000',
newpin: '',
secpin: '',
};
onPressButton = () => {
if (this.state.newpin == this.state.secpin) {
this.setState(
{ oldpin: this.state.newpin },
async() => await this.storeData());
}
else {
ToastAndroid.show("Password Unmatched", ToastAndroid.SHORT);
}
}
storeData = async () =>{
const {oldpin} = this.state;
let pin : oldpin;
try{
await AsyncStorage.setItem('mypin',pin);
ToastAndroid.show("Password Changed", ToastAndroid.SHORT);
}
catch (err){
console.warn(err)
}}
....
This is how I trying to retrieve data in screentwo.js:
class screentwo extends Component {
constructor(props) {
super(props);
this.onComplete = this.onComplete.bind(this);
this.state = {
pin: ''
};
}
retrieveData = async (mypin) => {
try {
let value = await AsyncStorage.getItem(mypin);
if (value !== null) {
console.log(value);
this.setState({
pin: value})
}
} catch (error) {
console.warn(err)
}
}
onComplete(inputtedPin, clear) {
retrieveData();
if (inputtedPin !== this.state.pin) {
ToastAndroid.show("Incorrect Pin", ToastAndroid.SHORT);
clear();
} else {
ToastAndroid.show("Pin is correct", ToastAndroid.SHORT);
clear();
this.props.navigation.navigate("Dashboard");
}}
....
Error:
Reference Error: ReferenceError:Can't find variable:retrieveData
Am I using the right way to stored and retrieve data?
Any suggestion?
Thank you.
There are a couple of issues that I can see with your code.
Firstly the retrieveData() function. It is asynchronous and should be called with await also you are getting the error: Reference Error: ReferenceError:Can't find variable:retrieveData because you haven't used this
So ideally you should call it await this.retrieveData();
There are a few more issues with this function. You use the parameter mypin but don't seem to pass any parameter to the function when you call it. Fixing this issue you should call retreiveData() like this:
await this.retrieveData('mypin');
Or you could remove passing the paramater altogether, which I will show how to do in my refactor below.
Finally you call retreiveData every time you check the inputtedPin this isn't that efficient, it is asynchronous so it may take some time, and secondly it also takes time for the setState function to complete, which means that the state may not have updated in time when you go to check it against the inputtedPin, meaning that you are checking the inputtedPin against the wrong value.
Code Refactor
This is how I would refactor your component.
Refactor retrieveData so that it no longer takes a parameter and the key is hardcoded in the .getItem
In the componentDidMount get the value of the pin from AsyncStorage and save it to state.
Remove the retrieveData call from onComplete
Here is the refactor
retrieveData = async () => { // parameter have been removed
try {
let value = await AsyncStorage.getItem('mypin'); // notice I am now passing the key as a string not as a parameter
if (value !== null) {
console.log(value);
this.setState({ pin: value })
}
} catch (error) {
console.warn(err)
}
}
// here we call the refactored retrievedData which will set the state.
async componentDidMount () {
await this.retrieveData();
}
onComplete(inputtedPin, clear) {
// we remove the call to retrieveData as we have already gotten the pin in the componentDidMount
if (inputtedPin !== this.state.pin) {
ToastAndroid.show("Incorrect Pin", ToastAndroid.SHORT);
clear();
} else {
ToastAndroid.show("Pin is correct", ToastAndroid.SHORT);
clear();
this.props.navigation.navigate("Dashboard");
}
}
only replace
retrieveData();
to
this.retrieveData();
When you call async method from a caller method that method also become async Try prefix
async onComplete () { await this.retrieveData() }
I want to use AsyncStorage but it returns [object object]:
Phone.js component:
commonHelper.setData("commonConstants.KEY_CODE",'code');
this.goTo('Activation');
Activation.js component:
const code = commonHelper.getData("commonConstants.KEY_CODE")
this.setState({searchString:code.toString()})
commonHelper.js:
function getData(key) {
try {
const value = AsyncStorage.getItem(key).then(val => {
return JSON.parse(val)
});
return value
} catch (err) {
throw err
}
}
function setData(key,value) {
try {
AsyncStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.log("Error saving data" + error);
}
}
where is my problem?
AsyncStorage is returning a promise. your getData returns that promise.
to read the data, you need to use a .then
commonHelper.getData("commonConstants.KEY_CODE")
.then(code => {
this.setState({searchString:code}) // or code.toString().. depends on what you stored
});`
Also, the return value in your getData function is necessary because you are returning the promise in .then
How to remove an item from AsyncStorage? right now I am trying this code:
AsyncStorage.removeItem('userId');
but this is not working for me.
Try this:
async removeItemValue(key) {
try {
await AsyncStorage.removeItem(key);
return true;
}
catch(exception) {
return false;
}
}
This is what I did, had a similar issue.It works well when you want to remove an item based on its id. make sure each item has a unique id.
remove_user = async(userid) => {
try{
let usersJSON= await AsyncStorage.getItem('users');
let usersArray = JSON.parse(usersJSON);
alteredUsers = usersArray.filter(function(e){
return e.id !== userid.id
})
AsyncStorage.setItem('users', JSON.stringify(alteredUsers));
this.setState({
users:alteredUsers
})
}
catch(error){
console.log(error)
}
};
This looks correct, but maybe you are trying to read back from AsyncStorage too soon? It's asynchronous, so the change isn't applied right away and you might still see the key if you try to get it on the following line. Try to call AsyncStorage.removeItem with await or do what you want to do in the callback.
this delete method which removes object from array by passing index (here i called id)
async deleteData(id) {
try {
this.state.item.splice(id, 1);
await AsyncStorage.setItem("mylist",JSON.stringify(this.state.item))
this.setState({ item: JSON.parse(await AsyncStorage.getItem("mylist")) })
} catch (error) {
console.log(error);
}
};
and call this by using onPress method, here i am using button and pass index
<Button onPress={this.deleteData.bind(this,index)}>delete</Button>
This is the framework code for AsyncStorage.removeItem:
removeItem: function(
key: string,
callback?: ?(error: ?Error) => void
): Promise {
return new Promise((resolve, reject) => {
RCTAsyncStorage.multiRemove([key], function(errors) {
var errs = convertErrors(errors);
callback && callback(errs && errs[0]);
if (errs) {
reject(errs[0]);
} else {
resolve(null);
}
});
});
}
As you can see above it requires the key(Which is name of the item you set in asyncstorage that you want to delete) and a callback function. Make sure you have the correct key and the correct params and it should work fine.
Use removeItem() method to remove values from AsyncStorage in react.
try {
await AsyncStorage.removeItem(key);
console.log('Data removed')
}
catch(exception) {
console.log(exception)
}
try this for react-native
const deletCar = async () => {
try {
await AsyncStorage.removeItem('#storage_Key').then(() => {
// props.navigation.navigate('same page name refresh ');
/* setprevCar({ carNumner: '', carModel: '' }) return empty obj if deleted. */
})
}
catch (exception) {
return false;
}
}
if you want to remove the selected list :-
let key =[
'visitorId',
'visitorMobile',
'visitorData',
]
await AsyncStorage.multiRemove(key)