0

Ok so what I'm trying to do is to retrieve the users credentials for the Google API from my mongoDB with a findOne() query in mongoose. I first tried doing it with callbacks but since it's async it kept going on and I'd end up with a call to the API without any credentials. I then tried using mongoose .exec() and then do a .then() to get the data, which I now can and everything is happening in the order I want it to. The problem is that I still can't get the credentials from within the Promise, and I need this to first refresh the access token and then return the entire oauth2Client in order to do various calls to the API.

function createAndUpdateOauth2Client(email) {
    var oauth2Client = new oauth(process.env.CLIENT_ID, process.env.CLIENT_SECRET, process.env.REDIRECT_URL);
    var credentials = User.findOne({email: email}, function (err, user) {
        console.log("Found user with email: " + user.email);
        console.log("Setting refresh_token to: " + user.googleTokens.refresh_token);
        //return user.googleTokens;
    }).exec();

credentials.then(function (user) {
    oauth2Client.credentials = user.googleTokens;
    console.log("Promise on query was just finished and client is now: ");
    console.log(oauth2Client);
});

var token = oauth2Client.getAccessToken(function (err, token) {
    if(err) {
        console.log(err);
        console.log("There was an error when retrieveing access_token");
        return null;
    } else {
        console.log("setting access_token to: " + token);
        return token;
    }
});

if(token) oauth2Client.credentials.access_token = token;

console.log("returning client: " + oauth2Client.credentials);
    return oauth2Client;

My problem is ofcourse that trying to set the credentials inside credentials.then() doesn't actually set it as it's still undefinied when I call the getAccessToken() function.

I thought of calling getAccessToken() from inside credentials.then() but in the end I still need the entire function to return the ouath2Client with the credentials from the database and the refreshed access_token from getAccessToken().

Anyone have any tips or tricks on how I can solve this?

  • `oauth2Client.getAccessToken` takes a callback, it doesn't appear to `return` anything. Try to use a promise there as well. You can access the `token` only inside the asychronous callback. – Bergi Mar 22 '17 at 19:34
  • @Bergi How do you mean? I do return token if it's found. Is there really no way to retrieve this to somewhere outside? Because I don't see how I can solve this otherwise. :/ – Hugo Lewenhaupt Mar 22 '17 at 19:48
  • You cannot expect a function to do asynchronous stuff and still return the result synchronously. The function will run to completion before any of the asynchronous code will have been executed. So... don't try to return the final value, but let your function return the promise. You must stick to the promise paradigm once you start with it. – trincot Mar 22 '17 at 19:51
  • @trincot how would I make my above function return an entire promise in the end that I can then use in my route that calls the function? – Hugo Lewenhaupt Mar 22 '17 at 19:53
  • (1) put `return ` before `credentials.then` so to return the promise. (2) Move all code from `var token` onwards inside that `then` callback making sure you return the value you need. So you could keep `return oauth2Client`, but from inside the `then` callback. That will be the promised value. – trincot Mar 22 '17 at 19:56

0 Answers0