13

In my React Native app's AsyncStorage, I have multiple JSON objects, each with a unique key id like so:

 '62834456':
 data: { "foo": "bar",
 "nicknames": [ "grizz", "example" ],
 ... and so on }

They have been pushed into AsyncStorage stringified. I'm trying to retrieve every object by their id, and push both the id and its' JSON data into the component's state. I have this so far:

// for every key in async storage, push to favorites in state
importData = (id) => {
  for (id in AsyncStorage) {
    return AsyncStorage.getItem(id)
      .then(req => JSON.parse(req))
      .then(json => console.log(json))
      .catch(error => console.log('error!'));
  }
}

When console.logging 'json' in the above function, the result is null. How can I properly access all JSON objects in my AsyncStorage?

FINAL EDIT

Using your code example and removing JSON.parse (so simply console.logging req) returns this: enter image description here

It appears this is happening because for some reason .forEach is returning the first string in the array, the array itself, then the second string.

zahnzy
  • 237
  • 1
  • 2
  • 13

6 Answers6

23

In order to get all AsyncStorage keys, you need to call AsyncStorage.getAllKeys(). In order to speed things up, you should also use AsyncStorage.multiGet() By doing that your code becomes;

importData = async () => {
  try {
    const keys = await AsyncStorage.getAllKeys();
    const result = await AsyncStorage.multiGet(keys);

    return result.map(req => JSON.parse(req)).forEach(console.log);
  } catch (error) {
    console.error(error)
  }
}
Tukan
  • 2,253
  • 15
  • 17
  • So it looks like id isn't being using in this case, do I need to define it somewhere before passing it into importData()? – zahnzy Jan 12 '18 at 18:47
  • Key is the id here, you can use normal getItem as keys is just an id array and connect them that way. – Tukan Jan 12 '18 at 18:50
  • Thank you for your help. At the moment, I am having trouble getting things to display in the console after parsing.. i.e. In your example, if I console.log(req), nothing will display, not even a generic object response, the console is blank. Is this not the proper way to view these objects after being parsed? – zahnzy Jan 13 '18 at 02:31
  • Could you check what is in keys? Perhaps there isn't anything set yet. – Tukan Jan 13 '18 at 07:00
  • I have edited my original post to give you the most information possible – zahnzy Jan 13 '18 at 16:51
  • @zahnzy If you look at the code I wrote, you might notice that I am using ```result.map```. Reason for this is simple, result in multiget is an array of strings. You need to parse each and every single one of them. What you are trying to do in your code is to parse an array into json, which returns null. – Tukan Jan 13 '18 at 19:33
  • 1
    Why mix async / await with then and callbacks? Why not go the whole way as in @georgekpc 's answer? – cammil Dec 08 '19 at 11:04
  • This is a year old answer so cannot really remember what was the idea. You got a point though, updating. – Tukan Dec 09 '19 at 12:44
6

here is a more elegant way to get all items using async/await functions

const fetchAllItems = async () => {
    try {
        const keys = await AsyncStorage.getAllKeys()
        const items = await AsyncStorage.multiGet(keys)

        return items
    } catch (error) {
        console.log(error, "problemo")
    }
}
georgekpc
  • 218
  • 3
  • 8
4

May be, little straight forward using promises.

import { AsyncStorage } from 'react-native';

  AsyncStorage.getAllKeys()
    .then((keys)=> AsyncStorage.multiGet(keys)
                    .then((data) => console.log(data)));

Cheers!

Ram Grandhi
  • 901
  • 7
  • 9
1

Something that I didn't prefer about the current answers is that it returns back an array of arrays which will make it harder to search for a specific key. Here is what I prefer to use:

const getAll = async () => {
  try {
    const result: any = {};
    const keys = await AsyncStorage.getAllKeys();
    for (const key of keys) {
      const val = await AsyncStorage.getItem(key);
      result[key] = val;
    }
    return result;
  } catch (error) {
    alert(error);
  }
};

This will return back an object with all the keys you have and their respective values.

Hossam Mourad
  • 4,369
  • 4
  • 26
  • 22
0

Code for return a json object

    try {
        const keys = await AsyncStorage.getAllKeys()
        const itemsArray = await AsyncStorage.multiGet(keys)
        let object = {}
        itemsArray.map(item => {
          object[`${item[0]}`] = item[1]
        })
        return object
    }   catch (error) {
        console.log(error, 'error')
    }
0

By using Object.fromEntries (doc)

const getAllData = async() => {
  try {
    const keys = await AsyncStorage.getAllKeys();
    const result = await AsyncStorage.multiGet(keys);
    const obj = Object.fromEntries(result);
    // obj be like {"key1": "value 1", "key2": "value 2", .....}
    // Now parse the 
    Object.keys(obj).forEach(key => {
      obj[key] = JSON.parse(obj[key]);
    });
  } catch (error) {
    console.error(error);
  }
};