0

Calling a external functions in nodejs as we do in javascript so that we can re-use the function but in my case its not working. Why?

I am guessing its working asynchronously in nodejs. How do I fix this? Callbacks? I am new to nodejs.

app.get('/googleSyncCallback', passport.authenticate('google', {
  failureRedirect: 'url'
}),

function(req, res) {

  var contacts = new GoogleContacts({
    token: req.token
  });
  var retrievedContacts = '';
  var retrievedContactsArr = [];

  contacts.getContacts(function(err, contacts) {
    contacts.forEach(function(entry) {
      retrievedContacts = {
        contact: {
          "phone": {
            "cell": entry.phoneNumber,
          }
        },
      }
      retrievedContactsArr.push(retrievedContacts);
      console.log('array... ', retrievedContactsArr[0]); //prints all values
    });
  });
  checkIfContactExists(req, res, retrievedContactsArr);
}
});

function checkIfContactExists(req, res, retrievedContactsArr) {
  //PRINTS UNDEFINED..
  console.log('array... ', retrievedContactsArr[0]); //// LINE 10
}

printing the array retrievedContactsArr[0] is returning undefined at line 10.

nem035
  • 31,501
  • 5
  • 73
  • 88
kittu
  • 5,835
  • 18
  • 72
  • 142
  • The asynchronous behavior you have here is not unique to node, it is standard in the javascript language across platforms. – nem035 Dec 20 '16 at 19:25
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – nem035 Dec 20 '16 at 19:26
  • @nem035 No usually this works in javascript. Its not working in nodejs only – kittu Dec 20 '16 at 19:26
  • is contacts.getContacts an async function? – nem035 Dec 20 '16 at 19:27
  • @nem035 its a npm package for google contacts: https://www.npmjs.com/package/google-contacts – kittu Dec 20 '16 at 19:28
  • *in nodejs as we do in javascript* — Node.js is to JavaScript as Firefox is to JavaScript. It is just a way to run JavaScript. The language works in exactly the same way. – Quentin Dec 20 '16 at 19:31
  • Sorry my friend, but this code will not work on any platform. The reason is that you're trying to access an asynchronous result in a synchronous manner. In other words, you're requesting the contacts from google but trying to use them before they arrive. Check out the attached suggested duplicate for many solutions to this – nem035 Dec 20 '16 at 19:31
  • 1
    Yes. You use a callback. You are already using a callback. You just put `checkIfContactExists(req, res, retrievedContactsArr);` one line too low. You closed the callback function before that line instead of after it. (Voting to close as typo). – Quentin Dec 20 '16 at 19:33
  • @nem035 But I am calling the function only after retrieving the contacts. I placed it outside of `getContacts` function – kittu Dec 20 '16 at 19:34
  • 1
    @Satyadev that is the exact problem :). It should be inside. The callback inside `getContacts` gets called **after** you receive the contacts but the line after `getContacts` gets called immediately. I highly suggest you look at [this question](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) for clarification. – nem035 Dec 20 '16 at 19:34
  • @Quentin Thanks Quentin for your observation. Thank you – kittu Dec 20 '16 at 19:36
  • I have experienced similar problems before. Sometimes the browser will execute code synchronously even though it should be asynchronous. I would consider this behaviour an optimization and unreliable -- meaning don't count on it. – Bijou Trouvaille Dec 20 '16 at 19:38
  • 1
    @nem035 okay I will look at it. Thank you :) – kittu Dec 20 '16 at 19:45

1 Answers1

0

You need to change to put your function inside the callback, you also need to add a callback to the function, as express can define middleware with the signature (req, res) that must run synchronously or return a promise or have the signature (req, res, next) where next is a callback.

app.get('/googleSyncCallback', passport.authenticate('google', {
  failureRedirect: 'url'
}),

function(req, res, next) {

  var contacts = new GoogleContacts({
    token: req.token
  });
  var retrievedContacts = '';
  var retrievedContactsArr = [];

  contacts.getContacts(function(err, contacts) {
    contacts.forEach(function(entry) {
      retrievedContacts = {
        contact: {
          "phone": {
            "cell": entry.phoneNumber,
          }
        },
      }
      retrievedContactsArr.push(retrievedContacts);
      console.log('array... ', retrievedContactsArr[0]);
      checkIfContactExists(req, res, retrievedContactsArr);
      next()
    });
  });

    }
    });

    function checkIfContactExists(req, res, retrievedContactsArr) {
      //PRINTS UNDEFINED..
      console.log('array... ', retrievedContactsArr[0]); //// LINE 10
    }
Peter Grainger
  • 3,001
  • 1
  • 12
  • 18