How to parse data from AsyncStorage to <Text>

#1

I am getting the following error when I get data from AsyncStorage:

Objects are not valid as a React child (found: object with keys {_40, _65, _55, _72})

async function setItem(key, value) {
  try {
    await AsyncStorage.setItem(key, value);
    console.log(key, value);
    return value;
  } catch (error) {
    // Handle errors here
  }
}

async function getItem(item) {
  try {
    const value = await AsyncStorage.getItem(item);
    console.log(value);
    return value;
  } catch (error) {
    // Handle errors here
  }
}

setVar = setItem('username', 'Name');
getVar = getItem('username');

I am getting the error when outputting the result to:

<Text>{getVar}</Text>

When I check console I get the required output/everything is correct but I cannot render the text to the screen.

Any help or suggestions would be greatly appreciated.

Thanks.

#2

I would double check your code if it is correct, rather are you passing a string always? try: console.log(typeof value) in your setItem wrapper.

1 Like
#3

Thanks for your reply, if I change code to:

console.log(key, typeof value);

and

console.log(typeof value);

The console log shows…

string

…for setItem and getItem, any ideas as to why it is not showing up in text?

#4

Ah, your function getItem is giving back a Promise, remember that async keyword automatically makes the function return Promise. Hence the error message, can’t put the Promise object in <Text>

2 Likes
#5

Interesting and thanks again for replying, I’ve been on this for hours :wink:

Any idea how I can update the code to get the stored value to <Text> ?

Am I correct in assuming the stored value can be displayed in <Text> if not how to I display a store value/is there another way to store and show data locally?

Many thanks for any advice.

#6

Sure, I mean

  1. Put the string you’ll use in state:
    state = {showThisText:''}

  2. in render: <Text>{this.state.showThisText}</Text>

  3. Then in async componentDidMount, get the data and do a this.setState({showThisText:YOUR_PULLED_STRING})

That’s it :slight_smile:

1 Like
#7

Many thanks, I’ve been looking at the logic of this for hours and needed some input on the structure, login and order of this.

I’ll post up my code when complete and working.

Thanks again for your time and help with this.

2 Likes
#8

Thanks again for the help, here is what worked:

  state = { username: '' };

  async componentWillMount() {
    const usernameGet = await AsyncStorage.getItem('username');
    if (usernameGet) {
      this.setState({ username: usernameGet });
    } else {
      this.setState({ username: false });
    }
  }

When using getItem it was also important to remove:

    console.log(value);
#9

Good, small thing, might be better to not mix up data types. As you have it, username is sometimes a bool and sometimes a string. Perhaps just let '' represent no known user

1 Like
#10

Not really answering your question but I suggest always use a JSON (for both set and get), to do that I’ve wrapped RN’s AsyncStorage and created the following helper class - this will handle a JSON for both set and get, and yes - I know I could’ve use async/await but decided to use .then anyway (don’t remember why), here it is:

import { AsyncStorage } from 'react-native';

export default {

    get: (key) => {

        return AsyncStorage.getItem(key).then((value) => {
            return JSON.parse(value);
        });

    },

    set: (key, json) => {

        const value = JSON.stringify(json);

        return AsyncStorage.setItem(key, value);

    },

    merge: (key, json) => {

        const value = JSON.stringify(json);

        return AsyncStorage.mergeItem(key, value);

    },

    clear: (key) => {

        return AsyncStorage.removeItem(key);

    }

}
2 Likes
#11

Many thanks for sharing this, I am making progress and would like to learn more from your code.

Please could you give an example of sending data to ‘set’ so I can see how you are doing it?

Thanks again.