cmcodes
cmcodes

Reputation: 1866

Warning: Possible Unhandled Promise Rejection

When I open my freshly build app for the first time, the following warning appears. I think it's because the key in AsyncStorage.getItem("KEY") doesn't have any value when app runs for the very first time. How do I handle this promise rejection?

warning output

this.state = {
      subjects: [],
      text: "",
      present_count: [0, 0, 0, 0, 0, 0, 0],
      total_count: [0, 0, 0, 0, 0, 0, 0],
      present: 0,
      total: 0
}
componentDidMount() {
    this._isMounted = true;
    Subjects.all(subjects => this.setState({ subjects: subjects || [] }));
    AsyncStorage.getItem("PRESENT_COUNT").then((value) => {
      this.setState({ present_count: JSON.parse(value || this.state.present_count) });
    });
    AsyncStorage.getItem("TOTAL_COUNT").then((value) => {
      this.setState({ total_count: JSON.parse(value || this.state.total_count) });
    });
    AsyncStorage.getItem("PRESENT").then((value) => {
      this.setState({ present: JSON.parse(value || this.state.present) });
    });
    AsyncStorage.getItem("TOTAL").then((value) => {
      this.setState({ total: JSON.parse(value || this.state.total) });
    });
  }

Upvotes: 0

Views: 467

Answers (3)

gdh
gdh

Reputation: 13682

One way is to check if value is all good.

AsyncStorage.getItem("PRESENT_COUNT")
  .then((value) => {
    this.setState({
      present_count: value ? JSON.parse(value) : this.state.present_count
    });
  })

Another way is to use catch block

AsyncStorage.getItem("PRESENT_COUNT")
  .then((value) => {
    this.setState({
      present_count: JSON.parse(value || this.state.present_count),
    });
  })
  .catch((err) => {
    console.log(err);
    this.setState({ someState: "someVal" }); // if required...
  });

Finally you can also consider to use promise.all as mentioned in another answer (by @wentjun). Just note that if any one of your api call is failed, you will end up in not setting any state. Also make sure to use try catch when using async/await.

Upvotes: 1

wentjun
wentjun

Reputation: 42516

It seems like AsyncStorage.getItem is an asynchronous operation. In that case, it will be necessary to await for the getItem operations to be completed. You can make use of Promise.all to wait for the getItem methods to be completed before updating the state.

async componentDidMount() {
  const getPresentCount = AsyncStorage.getItem('PRESENT_COUNT');
  const getTotalCount = AsyncStorage.getItem('TOTAL_COUNT');
  const getPresent = AsyncStorage.getItem('PRESENT');
  const getTotal = AsyncStorage.getItem('TOTAL');

  const [presentCount, totalCount, present, total] = await Promise.all([getPresentCount, getTotalCount, getPresent, getTotal]);
  this.setState({
    present_count: JSON.parse(value) || this.state.present_count,
    total_count: JSON.parse(value) || this.state.total_count,
    present: JSON.parse(value) || this.state.present,
    total: JSON.parse(value) || this.state.total,
  })
}

Upvotes: 1

royalbhati
royalbhati

Reputation: 306

You can use an if block inside .then

AsyncStorage.getItem("KEY").then((value) => {
          if(value){
          this.setState({ present_count: JSON.parse(value || this.state.present_count) });
        }
        });

Upvotes: 1

Related Questions