0

So I am porting my slackbot from python over to Node and am having issues with async/await. My function is completely ignoring the await keyword and the linter is giving me the following error:

'await' has no effect on the type of this expression.

Here is the code:

function list_channels(access_token) {
  fetch(`https://slack.com/api/channels.list?token=${access_token}`)
    .then((r) => {
      r.json()
      .then(c => {
        let channels = {}
        for (channel of c.channels) {
          channels[channel.name] = channel.id
        }
        return new Promise(resolve => {
          console.log("_______resolve", channels)
          resolve(channels)
        })
      })
    })

}

const wrapper = {
  list_channels: list_channels
}
module.exports = wrapper

and

  app.get('/admin', async (req, res) => {
    const user = req.user
    let a = await wrapper.list_channels(code)
    res.send({hmm:a})
  })

When I call the route, I get {}

  • You're not returning anything from list_channels, so it returns `undefined` and `await undefined` is just `undefined`. You should `return fetch(...` to fix it. You also don't need the inner Promise at all, just `return channels;` instead of `return new Promise` – Paul Mar 14 '20 at 03:56
  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – CertainPerformance Mar 14 '20 at 03:56
  • Thanks guys. I realized this after waking up today. Guess I had been mentally exhausted yesterday. – someone123 Mar 14 '20 at 14:22

1 Answers1

0

I rewrote your code keeping the var/function names (Although you should use better names)

async function list_channels(access_token) {
    let r = await fetch(`https://slack.com/api/channels.list?token=${access_token}`);
    let c = await r.json();
    let channels = {}
    for (channel of c.channels) {
        channels[channel.name] = channel.id;
    }
    console.log("_______resolve", channels);
    return channels;
}

module.exports = {list_channels} // Object with property list_channels

As you can see, you can use await instead using .then. Like that, you will avoid the callback hell problem, making you code more readable and easy to edit.

There is a nice explanation here: http://callbackhell.com/


If you really want to go on callback hell way, you can do something like:

function list_channels(access_token) {
    return new Promise(resolve => {
        fetch(`https://slack.com/api/channels.list?token=${access_token}`).then((r) => {
            r.json().then(c => {
                let channels = {}
                for (channel of c.channels) {
                    channels[channel.name] = channel.id
                }
                console.log("_______resolve", channels)
                resolve(channels)
            })
        })
    })   
}
  • Thank you so much! So just to be clear in your re-written Async/await part, we are just not returning something until await resolves? Lol i do need better names. I was just testing this because I wasn't confident with how things should be done.Thanks for the help! – someone123 Mar 14 '20 at 14:19
  • You're welcome! Yes, `await` waits the returned promise be resolved **and extracts the value resolved by the promise**. It have the same effect of using callbacks, but makes the life easier (Also called **syntactic sugar**). – Alan Vinícius Mar 15 '20 at 17:13
  • What I mean with **"and extracts the value resolved by the promise"**: https://jsfiddle.net/alanvncs/9tjpb82w/18/ – Alan Vinícius Mar 15 '20 at 17:34