Unable to get async/await working in react native - react-native

I have not been able to get async/await working in a react native project.
const async getUser = () => {
try{
let value = await AsyncStorage.getItem("user");
return value;
}
catch(e){
throw e
}
}
I always get an Unexpected token error. I have tried adding { "presets": ["react-native", "es2015", "babel-preset-stage-3"] } with the same result.
On version ^0.35.0

The syntax for async arrow functions is:
const getUser = async () => {
...
}

Related

Auth0 with react-native

I'm trying to Example repo. But when this call is executed: const { accessToken } = await getCredentials();, accessToken is undefined
I have created Auth0 Application and copy my domain and clientId
so plugins in app.json looks like this:
"plugins": [
[
"react-native-auth0",
{
"domain": "{MY_DOMAIN}"
}
]
],
Also have Auth0Provider who looks like this:
Auth0Provider domain={config.domain} clientId={config.clientId}
Callback and Logout urls are all set. Here is image literally from provided example:
and getCredentials keep throwing undefined after client login with Google
You can d two approaches here.
Using a loader and waiting until data loading.
Using useEffect() with Promise() or using only useEffect().
in the App.js
const { user, getCredentials} = useAuth0();
const [isLoading, setIsLoading] = useState(false);
const getUserMetadata = async () => {
setIsLoading(true);
const tokenData = await getIdTokenClaims();
if (tokenData) {
localStorage.setItem(USER_OBJECT_KEY, tokenData['__raw']);
setIsLoading(false);
}
};
useEffect(() => {
const storedAccessToken = localStorage.getItem(USER_OBJECT_KEY);
if (!storedAccessToken) {
getUserMetadata();
}
}, [getCredentials, user]);
if (isLoading) {
return <div>Loading...</div>;
}
return (
Your code.....
)

AsyncStorage has weird characters in React-Native

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);
});

Get item value from AsyncStorage in react-native

I am a beginner and still try to learn to react native so help me!
I want to access AsyncStorage.getItem value outside the function.
I will further explain via code
This is my code :
import {AsyncStorage} from 'react-native';
set that value on screen1
AsyncStorage.setItem('mobileno', JSON.stringify(MobileNo));
try to get that value on screen 2
AsyncStorage.getItem('mobileno', (err, MobileNumber) => {
let abc = MobileNumber;
console.log("abc value " + abc)
})
let { MobileNo } = abc;
console.log({MobileNo})
I want to access that abc value outside the function as let { MobileNo } = abc; but it shows the error!
note : [console.log("abc value " + abc) works perfectlly ]
Error
can't find variable abc
question
So, how can I access that abc or that AsyncStorage value for the whole page [outside that function]; Because I want to use that value in other function too!
In short, I want that stored value in AsyncStorage to use it in other function.
Thank you for contributing your precious time
constructor(props) {
super(props);
this.state = {
mobileNumber: '',
};
}
componentDidMount() {
AsyncStorage.getItem('mobileno').then((mobileNo) => {
if(mobileNo){
this.setState({mobileNumber: mobileNo});
console.log(this.state.mobileNumber);
}
});
}
render() {
return(
<View>
<Text>{this.state.mobileNumber}</Text>
</View>
);
}
In this case async/await is not necessary because .then() is only called after the getItem() function is done fetching the item.
In your code abc is called out of scope. abc is only declared in your callback. An alternative can be to create a class method that returns that data. I personally find the async/await syntax much cleaner and easier understand the .then() chains.
docs show an example of this
_retrieveData = async () => {
try {
const value = await AsyncStorage.getItem('mobileno');
if (value !== null) {
// We have data!!
console.log(value);
return value;
}
} catch (error) {
// Error retrieving data
}
}
import {AsyncStorage} from 'react-native';
Above AsyncStorage is Deprecated, Moved to React-Native-Community
you can use now
1 :- yarn add #react-native-community/async-storage
2 :- react-native link #react-native-community/async-storage
Code :-
import AsyncStorage from '#react-native-community/async-storage';
storeData = async () => {
try {
await AsyncStorage.setItem('#storage_Key', 'stored value')
} catch (e) {
// saving error
}
}
getData = async () => {
try {
const value = await AsyncStorage.getItem('#storage_Key')
if(value !== null) {
// value previously stored
}
} catch(e) {
// error reading value
}
}
Link :- https://www.npmjs.com/package/#react-native-community/async-storage
use the link
https://github.com/react-native-community/async-storage
Install
$ yarn add #react-native-community/async-storage
Link
React Native 0.60+
CLI autolink feature links the module while building the app.
React Native <= 0.59
$ react-native link #react-native-community/async-storage
Note For iOS using cocoapods, run:
$ cd ios/ && pod install
See docs for manual linking guide
Upgrading to React Native 0.60+
New React Native comes with autolinking feature, which automatically links Native Modules in your project. In order to get it to work, make sure you unlink Async Storage first:
$ react-native unlink #react-native-community/async-storage
Usage
Import
import AsyncStorage from '#react-native-community/async-storage';
Store data
storeData = async () => {
try {
await AsyncStorage.setItem('#storage_Key', 'stored value')
} catch (e) {
// saving error
}
}
Read data
getData = async () => {
try {
const value = await AsyncStorage.getItem('#storage_Key')
if(value !== null) {
// value previously stored
}
} catch(e) {
// error reading value
}
}

Failed in retrieve data from AsyncStorage

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() }

Get item from AsyncStorage in React Native

I have a list of companies in React Native.
When I click on one of those companies I get the url of the API that is used for selected company. Then I store it to AsyncStorage and then I show the login screen. The function is as follows:
selectCompany(data_url, e) {
AsyncStorage.setItem("data_url", JSON.stringify(data_url), () => this.props.login());
}
Then on login page if I click on sign in button I go to the onLogin function, the function is as follows:
onLogin: function() {
fetch(data.url + '/manager/api/v1/obtain-auth-token/', })
.then(function(body) {
return body.json();
}).then(function(json) {
.....
}).catch(function() {
....
});
},
And data.url comes from data.js file, and I try to get url from the data.js file as follows:
let data_url = AsyncStorage.getItem("data_url").then(json => JSON.parse(json));
module.exports = {
url: data_url,
.....
}
But it doesn't work. Any advice?
AsyncStorage is async, therefore data_url will not be defined until it's retrieved what its looking for, you would need to move the fetch into the promise thats returned from the get so it will run it once it's done getting the data. This might be one way you tackle it:
const data_url = () => AsyncStorage.getItem("data_url"); //change this into a function
module.exports = {
url: data_url,
.....
}
now inside your component...
onLogin: function() {
data.url().then((url) => {
fetch(JSON.parse(url) + '/manager/api/v1/obtain-auth-token/', })
.then(function(body) {
return body.json();
}).then(function(json) {
.....
}).catch(function() {
....
});
});
},
AsyncStorage.getItem is a promise and needs to await for response rather than accessing direct and the function calling it should be defined as async. Here is an example to retrieve from AsyncStorage..
export async function getAccessKey(){
let accessToken = await AsyncStorage.getItem(ACCESS_TOKEN);
return accessToken;
}