In which file do I set a key in react native async storage for the first time the app starts? - react-native

I am developing a react native app and I would like data persistence. Async storage is working fine as I expect it to, however the problem is that I initialize a key 'servers' in a component and and call the setItem function in componentDidMount function. Now because of this every time I terminate the app and run it again all the data from the previous session is removed as the 'servers' key is reset when the component is mounted. I understand why this is causing the problem so I want to know where should I set the key in my code that it will not reset on every time my component mounts.
This is the function that I call in componentDidMount. This is the only way to declare a key in Async storage correct? because without it I would not be able to call getItem.
const save = async () => {
try {
server_list = await AsyncStorage.setItem('server_list', JSON.stringify({servers: []}));
}
catch (e){
console.log("Failed to load")
}
}

You can achieve this by filling the AsyncStorage only as long as there is no data under the server_list key.
This would look like this:
setServerList = async (value) => {
try {
const serverList = await AsyncStorage.getItem('server_list');
if(serverList === null) {
await AsyncStorage.setItem('server_list', value)
}
} catch(e) {
// save error
}
console.log('Done.')
}
You can still call this in the componentDidMount and your server list will no longer be overwritten

Related

React-Native async-storage putting functions in common js file?

In React-native (to which I'm relatively new), I use async storage to store a list of favourites between sessions.
eg
const StoreFavourites = async (sFavourites) => {
try {
await AsyncStorage.setItem(storageKeyFavourites, sFavourites);
} catch (e) {
// saving error
Alert.alert('Unable to store favourites')
}
}
const getFavourites = async () => {
try {
const value = await AsyncStorage.getItem(storageKeyFavourites)
if (value !== null) {
checkPageIsFavourite(value, false)
}
} catch (e) {
// err
}
}
As this will be used on multiple pages, I thought it would be good to store the code once in an external file, so I moved it to
PersistenStorage.js
and in the page, added
import * as pStorage from './PersistentStorage.js'
From my main component, I can then call
pStorage.StoreFavourites('somevalue')
and
pStorage.getFavourites()
which work, but I can't find a way for the getFavourites to call functions in the main component (ie which imports the external code)
checkPageIsFavourite(value, false)
can't run as it can't access this function from the external file.
Hope this is clear and is there a way around this? in other words, once the async get has completed, call functions in the main file.

null is not an object (using async storage)

I'm trying to implement secure store (like async storage) into my testproject and it works. The only thing that doesn't work appears to be my load() useEffect that runs every time I start a new session.
So every time I start the session "null is not an object" appears and throws errors at every part where I'm looking for my list on my home-screen (my state is called goals).
but if I temporarily turn it off, add a goal to my list, and then turn it on - it works fine every time I restart the app
I feel like I need to write a condition in my load() statement but I can't figure out what, I think the app runs the load() and gets stuck at the statements where I use goals before I've added any. Can someone help me here? I've tried if (goals !== null) but it doesn't work.
const [goals, setGoals] = useState([])
const load = async() => {
if (goals !== null) {
try {
const goalsValue = await SecureStore.getItemAsync('Goals');
setGoals(JSON.parse(goalsValue))
} catch (err) {
alert(err)
}
}
}
useEffect(()=> {
load()
},[])
So what is happening is that there's nothing inside goalsValue so when you try parsing it you get an error. To avoid that you should add an if statement that checks if it's empty or not
const [goals, setGoals] = useState([])
const load = async() => {
if (goals !== null) {
try {
const goalsValue = await SecureStore.getItemAsync('Goals');
if(goalsValue) setGoals(JSON.parse(goalsValue))
}catch (err) {alert(err)}
}}
useEffect(()=> {
load()
},[])
Try this and let me know if it works ☺️

Run An Function Only Once Per App Installation In React Native ( Class Component )

So I Have A Issue Here I Just Want To Run An Function Only Once In The App
I Need To Initialize An Empty Array Only Once To The Async Storage . The I Will Do Read And Write Functions In The Array Later On Using ComponentWillMount() ...
The Issue Is How Do I Initialise A Empty Array at First And I Don't Want It To Be Empty Later On ( Like When The App Is Closed And Opened )
Each Time The Screen Renders I Read The Data Stored In The Async Storage ... But When The Screen Renders For The First Time The App Is Installed ... I Have Not Called The Below Function
setObjectValue = async () => {
try {
const jsonValue = JSON.stringify(this.state.data)
await AsyncStorage.setItem('Emails', jsonValue)
this.setState({ value : this.state.data.length })
} catch(e) {
// save error
}
console.log('Done.')
}
But In Case I Call It Before The Reading ... It Erases The Existing Data And Sets It To An Empty Array ( Becuase I Have An Contructor Which Has data: [ ] ) so when i read the data i get an empty array
You Can See The Full Code Here - https://snack.expo.io/#belgin/budget-tracker
Thanks To Any One Who Helps : )
There are few changes that are required in your app.
First replace UNSAFE_componentWillMount with componentDidMount
And change your getMyObject like below which will make sure that it only updates if the value is there
getMyObject = async () => {
try {
const jsonValue = await AsyncStorage.getItem('Emails');
if (jsonValue) {
const data = JSON.parse(jsonValue);
this.setState({ data: data, value: data.length });
}
} catch (e) {
// read error
}
};
Also remove the setState calls from the functions that you update the asyncStorage this will show invalid data as your calls are done while the state is not updated.
Also you can update the asyncStorage after the state is updated like below
this.setState({ data: this.state.data },()=>this.setObjectValue());

Can I use a function with async await inside ComponentDidMount in React Native?

I am using AsyncStorage.getItem in React Native.
As soon as the Application loads, I want to get the saved data in the device memory using AsyncStorage.getItem. I thought of using ComponentDidMount(). So as soon as the components are loaded, I want to run the AsyncStorage.getItem automatically and save the data to the array DATA. This way the user will not push any button to start rendering what is saved on the memory of the device.
I used the code below, but I do not see any console.log activity. But the console.log works on my other pages on same program here. It seems the ComponentDidMount() did not get executed.
Thanks!
componentDidMount(){
async () => {
try {
const HomeData = await AsyncStorage.getItem('#MyApp_Homekey')
return HomeData
} catch (e) {
console.log('There was error.')
}
if(!HomeData){
console.log('There are no Dimmer Light saved in the memory.')
}
else {
console.log('There is value in data after getItem.')
this.setState(DATA = HomeData)
}
}
As metioned in comment you should use async for componentDidMount as:-
componentDidMount = async () => {
const HomeData = await AsyncStorage.getItem('#MyApp_Homekey')
if(!HomeData){
console.log('There are no Dimmer Light saved in the memory.')
}
else {
console.log('There is value in data after getItem.')
this.setState(DATA = HomeData)
}
}

Waiting for AsyncStorage.getItem()

I am using AsyncStorage in my React Native application to store information about the user. The getItem() function is asynchronous and requires me to implement a callback when I want to load data from the storage system.
AsyncStorage.getItem("phoneNumber").then((value) => {
this.setState({"phoneNumber": value});
}).done();
Because retrieving a value from the storage does not take long, I would like to wait until the operation is complete before continuing execution.
Is it possible to load data in a way that is not Asynchronous? If not, is there an easy way for me to wait until the getItem() call is complete to continue executing?
You can try either add a then after your getItem.
AsyncStorage.getItem("phoneNumber").then((value) => {
this.setState({"phoneNumber": value});
})
.then(res => {
//do something else
});
Or use await to wait the async operation to finish
var value = await AsyncStorage.getItem(STORAGE_KEY);
//use value to do something else.
try this option and you will not get the
Syntax Error: Await is a reserved word
async getData() {
return await AsyncStorage.getItem("#App:KEY");
}
You can try this:
async getPhoneNumber() {
const phoneNumber = await AsyncStorage.getItem("phoneNumber")
console.log(phoneNumber)
}