0

I have a helper function:

export async function isFavorite(id) {
  try {
    let favorites = await AsyncStorage.getItem("@rn-food-app:favorites");
    if (favorites) {
      return JSON.parse(favorites).includes(id);
    }
    return false;
  } catch (error) {
    return false;
  }
}

which I'm calling like this:

class DetailScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      recipe: null,
      isFavorite: false,
    };
  }

  componentDidMount() {
    const { route } = this.props;

    if (route.params && route.params.recipeId) {
      const recipe = getRecipe(route.params.recipeId);
      this.setState(
        {
          recipe,
        },
        () => {
          this.checkIfFavorite();
        }
      );
    }
  }

  checkIfFavorite() {
    const { recipe } = this.state;

    console.log(isFavorite(recipe.id));
  }

... ... ...

but the console.log() returns something like this

Promise {
  "_U": 0,
  "_V": 0,
  "_W": null,
  "_X": null,
}

instead of a bool.

I can make it work like this:

export async function isFavorite(id) {
  try {
    return await AsyncStorage.getItem("@rn-food-app:favorites");
  } catch (error) {
    return false;
  }
}

and then in the DetailScreen component

  checkIfFavorite() {
    const { recipe } = this.state;

    isFavorite(recipe.id)
      .then((res) => {
        const favorite = JSON.parse(res).includes(recipe.id);
        console.log(favorite);
      })
      .catch((err) => console.log(err));
  }

This works but why doesn't the approach above work? I wanted to extract all this logic into a helper function so I can simply call isFavorite: bool inside my components without extra logic.

2 Answers 2

1

It seems like you are not resolving your promise correctly thats why you get that weird looking console.log

Take a look at this example and change it to your needs - when getting the item from AsyncStorage I am calling 2x .then() calls and 1x .catch() call.

You can store and retrieve your data like this with AsyncStorage:

  const storeData = async (key, value) => {
    try {
      await AsyncStorage.setItem(key, value); 
    } catch (error) {
      console.log(error);
    }
  };

  const getData = async key => {
    try {
      const data = await AsyncStorage.getItem(key);
      if (data !== null) {
        console.log(data);
        return data;
      }
    } catch (error) {
      console.log(error);
    }
  };

then call getData with the key name like you stored your value wherever you want and set the key to a state value.

Store the value:

storeData("@rn-food-app:favorites", the value);

get the value:

  await getData"@rn-food-app:favorites") 
    .then((data) => data)
    .then((value) => this.setState({ isFavorite: value }))
    .catch((err) => console.log("AsyncStorageErr: " + err));
Sign up to request clarification or add additional context in comments.

1 Comment

Yes this approach works, I just thought that the first promise inside getData would handle this and you won't need to call await getData() ... later on
0

You are logging out Promise instead of an actual result of a Promise, something like this would:

 async checkIfFavorite() {
    const { recipe } = this.state;
    const isFav = await isFavorite(recipe.id) 

    console.log(isFav);
  }

or something along those lines would work

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.