vincent O
vincent O

Reputation: 538

storing array state objects in asyncStorage

I want to store an array state using async storage. but everytime i reload the app, it comes up blank. below is a sample code, and I have shown only the functions for better clarity.

    componentDidMount() {
      this.getDataSync();
    }


  getDataSync = async () => {
    try {
      const list = await AsyncStorage.getItem(LIST_STORAGE_KEY);

      const parsedList = JSON.parse(list);
      const obj = Object.keys(parsedList);

      this.setState({ isDataReady: true, list: obj || [] });
    } catch (e) {
      Alert.alert('Failed to load list.');
    }
  }

  handleAdd() {
    const { firstname, lastname, email, phone} = this.state;
    const ID = uuid();
    const newItemObject = {
        key: ID,
        firstname: firstname,
        lastname: lastname,
        email: email,
        phone: phone,
        image: null,
    };

    this.setState(prevState => ({
      list: [...prevState.list, newItemObject]
    }));

    this.saveItems(this.state.list);

  }

  saveItems = list => {
    AsyncStorage.setItem(LIST_STORAGE_KEY, JSON.stringify(list));
  };

Upvotes: 2

Views: 533

Answers (2)

Junius L
Junius L

Reputation: 16132

You are not saving your list but getting keys from the list. const obj = Object.keys(parsedList); you are saving array indexes to state.

getDataSync = async () => {
  try {
    const list = await AsyncStorage.getItem(LIST_STORAGE_KEY);

    const parsedList = JSON.parse(list);

  this.setState({ 
     isDataReady: true, 
     list: Array.isArray(parsedList) && parsedList.length && parsedList || [] 
  });

 } catch (e) {
    Alert.alert('Failed to load list.');
  }
}

Also pass saveItems as a callback to save the correct data.

this.setState(prevState => ({
  list: [...prevState.list, newItemObject]
}), () => this.saveItems(this.state.list));

Upvotes: 4

Ori Drori
Ori Drori

Reputation: 191976

The .setState() method is may be asynchronous, so the result of setting the state, cannot be used immediately after setting it. If you want to use the results of setting the state, you should use the callback (2nd param), which is called after the state is actually set:

this.setState(
  prevState => ({
    list: [...prevState.list, newItemObject]
  }),
  () => this.saveItems(this.state.list)
);

Upvotes: 0

Related Questions