0

I am using fetch method to get some data from the server. Once I get that data, I need to store some of it (access_token to be more precise cause I am using oauth) in AsyncStorage. I tried doing just AsyncStorage.setItem without await, not how it is shown in https://facebook.github.io/react-native/docs/asyncstorage, and it worked just fine.

I changed it to:

fetch ('site/login', POST ...)
.then((response) => response.json())
.then(async(responseJson) => {
   if (user.valid)
    await AsyncStorage.setItem('access_token', responseJson.token);

And it works fine too. But I have 2 questions now:

Is my implementation with fetch and async correct?

And what might happen if I don't use await/async in this case?

Sorry, I am kinda new to Promises and Asynchronous methods in Javascript. Thanks!

good_evening
  • 21,085
  • 65
  • 193
  • 298
  • the implementation you mentioned above is right. if you don't use await/async in this case, you would get the result of Promise clause. – crystal_17 Sep 12 '18 at 18:30
  • piece of advice: read about promises especially about chaining them(.then() may return another Promise or non-Promise result and there is a difference in processing). it would also really help on understanding how `async/await` is working under the hood. p.s. and this will explain better why there is no need in async/await inside of chained `.then` as Jared Smith demonstrates. pps Promises are really fun – skyboyer Sep 12 '18 at 18:36
  • Well if you don't want to wait for something, you can [just fire and forget it](https://stackoverflow.com/a/32385430/1048572). But usually your caller might expect that after your function is done the token is saved in the storage, and code that depends on this might break. – Bergi Sep 12 '18 at 19:47

1 Answers1

5

async/await is just syntactic sugar over Promises. You're already using Promises, so there's no need to do that. Just return the Promise:

fetch ('site/login', POST ...)
.then((response) => response.json())
.then((responseJson) => {
  if (user.valid) { // not sure where 'user' came from, but whatever
    return AsyncStorage.setItem('access_token', responseJson.token);
  } else {
    throw new Error('Invalid user');
  }
})
.then(_ => { // storage set, don't care about return value
  // do stuff
})
.catch((err) => {
  // handle error, including invalid user
});

Response to question in comments

The above in async/await would look like this:

async function foo() {
  try {
    const response = await fetch('site/login', POST ...);
    const responseJson = await response.json();
    if (user.valid) {
      return await AsyncStorage.setItem('access_token', responseJson.token);
    } else {
      throw new Error('Invalid user');
    }
  } catch (error) {
    // deal with errors
  }
}
Jared Smith
  • 19,721
  • 5
  • 45
  • 83
  • Thanks a lot! And what if I didn't use Promises? Would it not work then without await? – good_evening Sep 12 '18 at 18:35
  • 1
    @good_evening updated my answer. You have no choice but to use Promises because that's what `fetch`, `response.json()`, etc. return, but you can sugar over them with `async/await`. But it's still Promises under the hood, and `foo` will always return a Promise. – Jared Smith Sep 12 '18 at 18:41