1

Hello after setup a simple async function with promise return i'd like to use then promise instead of try! But is returning

await is a reserved word

for the second await in the function.

i've tried to place async return promise the data! but did not worked either

async infiniteNotification(page = 1) {
    let page = this.state.page;
    console.log("^^^^^", page);
    let auth_token = await AsyncStorage.getItem(AUTH_TOKEN);
    fetch(`/notifications?page=${page}`, {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Access: auth_token
      },
      params: { page }
    })
      .then(data => data.json())
      .then(data => {

        var allData = this.state.notifications.concat(data.notifications);
        this.setState({
          notifications: allData,
          page: this.state.page + 1,

        });
        let auth_token = await AsyncStorage.getItem(AUTH_TOKEN);
          fetch("/notifications/mark_as_read", {
          method: "POST",
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
            Access: auth_token
          },
          body: JSON.stringify({
            notification: {
              read: true
            }
          })
        }).then(response => {
          this.props.changeNotifications();
        });
      })
      .catch(err => {
        console.log(err);
      });
  }

> await is a reserved word (100:25) let auth_token = await AsyncStorage.getItem(AUTH_TOKEN); ^ fetch("/notifications/mark_as_read", {

hem
  • 1,012
  • 6
  • 11
Danks
  • 113
  • 2
  • 10
  • 3
    your inner functions aren't async. i'd avoid using `.then` – Daniel A. White Jul 08 '19 at 18:15
  • 1
    why use a mix of async await and promise.then? This looks like a good place to do a little refactoring, make your requests individual functions, await those that way you can remove the promise.then callbacks – John Ruddell Jul 08 '19 at 18:16
  • 3
    `.then(async (data) => {`. You can define inline async callbacks. – Emile Bergeron Jul 08 '19 at 18:16
  • ok, thank you guys! – Danks Jul 08 '19 at 18:31
  • @EmileBergeron No, [don't mix `async` functions into a `.then(…)` chain](https://stackoverflow.com/a/54387912/1048572)! – Bergi Jul 08 '19 at 18:37
  • @Bergi it's a matter of preferences. I never use aync/await as a personal preference. Your comment should say: _Preferably stick with one or the other, but avoid mixing both style_. – Emile Bergeron Jul 08 '19 at 18:53
  • @EmileBergeron Yes, that's precisely what I meant: don't mix them. – Bergi Jul 08 '19 at 18:55
  • @Bergi "**No, don't**" sounds like it won't work. While it does work, I agree that it's inconsistent! – Emile Bergeron Jul 08 '19 at 18:57
  • 1
    it was a link though so theres a little more context :) – John Ruddell Jul 08 '19 at 18:58
  • My comment still stands, _you can define inline async callbacks_ and it's the thing OP needed. The "don't mix" styles should have been directed to OP, not me. – Emile Bergeron Jul 08 '19 at 19:03
  • agreed, what you posted is valid. Its generally not a good practice but still valid. I think it was directed at both the OP and you, in the sense that @Bergi was saying you shouldn't recommend something that isn't a good practice. Like i could recommend someone writes 3 for loops to accomplish something 1 for loop would, and technically it is valid.. but that doesn't mean i should recommend it. Anyways thats what I gathered from that comment :) – John Ruddell Jul 08 '19 at 19:18
  • So, should i continue use or not? – Danks Jul 08 '19 at 19:45
  • You should be consistent @Danks. Its probably best to use async await for everything. – John Ruddell Jul 08 '19 at 19:49
  • 1
    Ok! @JohnRuddell, thank you very much man! and thank you for your answer on refactoring and code exemple! – Danks Jul 08 '19 at 20:24
  • @Danks yep! happy to help! :) when you start copy pasting things or are re-writing things its usually a good time to stop and think about how you are using it and use cases that give cadence for a refactor :) Happy coding! – John Ruddell Jul 08 '19 at 20:26
  • ok! @JohnRuddell, thanks for the tip! so long story short in any promise just use try catch statement! :) – Danks Jul 08 '19 at 20:29
  • 1
    well try catch with async await. if you were using promises you can `.then` and `.catch` to essentially do the same thing – John Ruddell Jul 08 '19 at 20:31
  • @JohnRuddell I was not recommending to mix both styles, just casually mentioning the missing inline `async`. It could happen outside of a promise chain and could be useful to OP to know that it works like that. It's good as well to share the good practices on top of that like you both did, but don't blame me for helping! – Emile Bergeron Jul 08 '19 at 20:50
  • 1
    Not blaming or passing blame or anything. Just interpreting the comment made by another around the intent of the comment. Hence my upvote on your comment about the inline async :) I think there's valid points on both sides. – John Ruddell Jul 08 '19 at 21:18

1 Answers1

2

You should refactor how you make your requests. I would have a common function to handle setting up the request and everything.

const makeRequest = async (url, options, auth_token) => {
  try {

    // Default options and request method
    if (!options) options = {}
    options.method = options.method || 'GET'

    // always pass a body through, handle the payload here
    if (options.body && (options.method === 'POST' || options.method === 'PUT')) {
      options.body = JSON.stringify(options.body)
    } else if (options.body) {
      url = appendQueryString(url, options.body)
      delete options.body
    }

    // setup headers
    if (!options.headers) options.headers = {}
    const headers = new Headers()
    for(const key of Object.keys(options.headers)) {
      headers.append(key, (options.headers as any)[key])
    }

    if (auth_token) {
      headers.append('Access', auth_token)
    }
    headers.append('Accept', 'application/json')
    headers.append('Content-Type', 'application/json')

    options.headers = headers

    const response = await fetch(url, options as any)
    const json = await response.json()
    if (!response.ok) {
      throw json
    }
    return json
  } catch (e) {
    console.error(e)
    throw e
  }
}

appendQueryString is a little helper util to do the get qs params in the url

const appendQueryString = (urlPath, params) => {
  const searchParams = new URLSearchParams()
  for (const key of Object.keys(params)) {
    searchParams.append(key, params[key])
  }
  return `${urlPath}?${searchParams.toString()}`
}

Now, to get to how you update your code, you'll notice things become less verbose and more extensive.

async infiniteNotification(page = 1) {
  try {
    let auth_token = await AsyncStorage.getItem(AUTH_TOKEN);
    const data = await makeRequest(
      `/notifications`,
      { body: { page } },
      auth_token
    )
    var allData = this.state.notifications.concat(data.notifications);
    this.setState({
      notifications: allData,
      page: this.state.page + 1,
    });
    const markedAsReadResponse = makeRequest(
      "/notifications/mark_as_read",
      {
        method: "POST",
        body: {
          notification: { read: true }
        },
      auth_token
    )
    this.props.changeNotifications();
  } catch (e) {
    // TODO handle your errors
  }
}
John Ruddell
  • 25,283
  • 6
  • 57
  • 86