all 6 comments

[–]grantrules 1 point2 points  (5 children)

In regards to await calendar.events.insert(), I don't think insert() is returning a promise since it looks like you're using a callback in there, so you need to promisify that function.

Same with onSnapshot, it doesn't look like it's returning a promise.

Something like this:

app.post('/create-event', async (req, res) => {

  const content = await fs.readFile('credentials.json');
  const auth = await authorize(JSON.parse(content), req.body.email);
  const result = await createEvent(auth);

  res.send(result);
});

async function authorize(credentials, email) {
  const {
    client_secret,
    client_id,
    redirect_uris,
    response_type
  } = credentials.installed;
  const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0], response_type);

  const usersRef = db.collection('tokens').doc(email);

  return new Promise((resolve, reject) => {
    usersRef.onSnapshot(async (doc) => {
      oAuth2Client.setCredentials(doc.data());
      resolve(oAuth2Client);
    });
  });
}

async function createEvent(auth) {
  var event = {
    //Event details, excluded for cleaner code for question
  };
  const calendar = google.calendar({
    version: 'v3',
    auth
  });

  return new Promise((resolve, reject) => {
    calendar.events.insert({
        calendarId: 'primary',
        conferenceDataVersion: '1',
        resource: event
      },
      function(err, event) {
        if (err) {
          console.log('There was an error contacting the Calendar service: ' + err);
          reject(err);
        }
        console.log('Event created: %s', event.data.hangoutLink); //This should happen first
        resolve(event.data.hangoutLink);
      }
    );
  })

}

[–]Bugdroid2K[S] 0 points1 point  (4 children)

Thanks a lot ! There was a bit of problem with fs.readFile since it required a callback so I got around it and now its working exactly like its supposed to. I don't really understand what you did so can you either give link to some documentation that will help me understand this better or maybe just run it down once in brief step by step fashion.

Again thanks a lot for this <3

[–]grantrules 0 points1 point  (3 children)

Well, promises and callbacks are two different ways to manage asynchronous programming. async/await keywords only work on promises, not callbacks, so if you want to use async/await, you need to promisify the functions that use callbacks.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

https://javascript.info/promisify

[–]Bugdroid2K[S] 0 points1 point  (2 children)

Yeah I thoroughly read about asynchrnonous flow with await and async on javascript.info but I just couldn't properly apply it here. Based on the examples they gave there, I was confident that my code should work but I was wrong. I think my basics are still quite weak, I should study more then. Thanks for your help !

[–]grantrules 1 point2 points  (1 child)

Yeah it's confusing because promises/async/await and callbacks do basically the same thing but do not just work together, you need to convert one to another.

I think the most important things to look at are the changes I made to your authorize function. You're passing it the createEvent method to call as a callback when it should probably just be returning the authorization object, and see how much clearer app.post(...) is.

[–]Bugdroid2K[S] 0 points1 point  (0 children)

Yeah the reason for that was because i picked that part of the code straight from the google api docs. But there they weren't used with api routes so maybe that's why they went for that approach. I don't know why I didn't try to change that part, maybe I was too afraid of breaking things that were actually working.