Awaiting functions in parameter

275 Views Asked by At

I want to await the function call which is passed in the parameter from the in-built google API call and return the results after it parameter function is executed. But I'm not able to get on with it.

async function list(auth, userId) {
    const gmail = google.gmail({ version: 'v1', auth });
    const result;
    await gmail.users.messages.list({
        userId: userId,
    }, async (err, res) => {
        if (err) return console.log('The API returned an error: ' + err);
        console.log(res.data);
        result = await res.data;  // I want to await this part
    });

    return result;
}
...

const returnedResult = await list(auth, id);
console.log(returnedResult); 

What happens in the above code is that 'result' and 'returnResult' remain undefined and are output first and then res.data is logged into the console. Any help would be appreciated. Thanks in advance


Edit:

Though the workaround is there to await such a call as answered below. But It still doesn't answer the internal mechanism through which it attains two forms while making API requests i.e. How

gmail.users.messages.list({...}, (err, res){...});

can be internally converted to

let result = await gmail.users.messages.list({});

or vice versa. The one possible explanation seems to be method overloading. But even this concept doesn't explain it since both the calls have exactly the same functionality. And for the first implementation since it is also a call involving promises it should still have some mechanism to await the request.

2

There are 2 best solutions below

1
fardjad On

With regards to the following:

result = await res.data; // I want to await this part

Awaiting on a non-promise value wouldn't help solving your problem. Assuming gmail.users.messages.list(...) returns a promise, instead of setting the result in the onFulfilled function, try this:

async function list(auth, userId) {
  // ...

  let result;
  try {
    result = await gmail.users.messages.list({ userId: userId });
  } catch (ex) {
    console.error('The API returned an error', ex)
  }

  return result;
}
1
DrusePstrago On

Though it's not the exact answer of how to await the functions in parameter, but the workaround such cases. In my case replacing

await gmail.users.messages.list({...}, (err, res) => {...});

with

try{
   const res = await gmail.users.messages.list({user: userId});
   console.log(res.data);
   return res.data
} catch(err) {
   return console.log('The API returned an error: ' + err);
}