0

I have a function in a utils file that I want to call and assign the exported result to a variable.

Currently, the variable is defined then I try to assign the return result but I am getting undefined as the result when I console.log it.

Here is my utils/consul file

var consul = require("consul")({host: config.consul.host'});
var consulBase = [];
var options;

module.exports = {
  consulQuery:  function(service){
      consul.catalog.service.nodes(service, function(err, results) {
          if(err) {console.log(err); throw err;}
           if(results.length <= 0) return {message: `Error could not find any service of ${service} registered with consul,`, errorCode: 500};
          if(results.length > 0) consulBase = [];
          results.forEach((result) => {
            consulBase.push(result.ServiceAddress+ ':' +result.ServicePort);
          });
          var serviceURL = 'http://' + consulBase[Math.floor(Math.random()*consulBase.length)];
          return options = {
            baseUrl : serviceURL,
            form: {'':''},
            headers: {authorization: ''}
          };    
        });
    }

Then in another file, I am calling like this and then trying to assign the value to 'options' but am getting undefined.

var consulQuery = require("../utils/consul").consulQuery;

// Get options array right away
var options = consulQuery('auth');

// Get options array every 5 seconds
setInterval(() => {
  options = consulQuery('auth');
  console.log(options);
}, 5 * 1000);
joshk132
  • 1,011
  • 12
  • 37
  • 3
    Possible duplicate of [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 Feb 09 '19 at 01:16
  • @CertainPerformance How is it a duplicate? My question and it are different. I looked at it and do not see how it solves my problem. – joshk132 Feb 09 '19 at 01:26
  • The problem is almost exactly the same. You're trying to return the response from an asynchronous call. – CertainPerformance Feb 09 '19 at 01:27
  • ^The essence of the problem is the same, and to solve it you will need to understand how both of those problems boil down to the same: returning a variable from an async call. – Azami Feb 09 '19 at 01:29
  • @MadWard I don't get it.... If I did then I would not be saying it's different. Maybe an explanation would be helpful since a link to something that seems unrelated and does not offer anything helpful to me isn't going to even come close to resolving my issue. – joshk132 Feb 09 '19 at 01:36
  • All the explanations are in the related question really, they explain the problem in length, and how to solve it (with callbacks, or with promises). I'm all for helping so you could mail me if you want and I'd send you a working version of your code, but your best choice is most likely to read the related question and its answers in depth. – Azami Feb 09 '19 at 01:46
  • Okay so I keep staring at the linked wrong answer and while both questions ask about undefined results that one is async and I don't think mine is. Maybe someone can give an example of how to do it because I don't understand – joshk132 Feb 09 '19 at 01:46
  • 1
    `consul.catalog.service.nodes(service, function(err, results) {`: this function has a callback as a second argument = it is asynchronous. If it wasn't, there would be no reason whatsoever to take a callback as argument. – Azami Feb 09 '19 at 01:48
  • @MadWard I'm sorry if I came across bad last night, had the worst week in a while, should not have been on the internet. And oh okay I always thought of callbacks as sync not async. – joshk132 Feb 09 '19 at 13:49
  • @JoshKirby Don't worry about it. The sole reason for callbacks to exist are because of asynchronicity: if the function was synchronous, it would just `return` the variable needed instead of passing it to a callback. – Azami Feb 09 '19 at 13:55

1 Answers1

0

OK you have a couple issues.

First, is conceptual about what you are trying to do. Second is what do you actually need to change in your code to make it work.

I will not talk about the first part because, and there are plenty of good resources to learn about async with examples better then I can do here.

For the actual problems with your code:

  1. You are missing a callback for consulQuery()

It should be something like this (notice the cb i added):

module.exports = {
    consulQuery: function (service, cb) {
        consul.catalog.service.nodes(service, function (err, results) {
            if (err) {
                console.log(err);
                cb(err, null)
                throw err;
            }
            if (results.length <= 0) return {
                message: `Error could not find any service of ${service} registered with consul,`,
                errorCode: 500
            };
            if (results.length > 0) consulBase = [];
            results.forEach((result) => {
                consulBase.push(result.ServiceAddress + ':' + result.ServicePort);
            });
            var serviceURL = 'http://' + consulBase[Math.floor(Math.random() * consulBase.length)];
            cb(null, {
                baseUrl: serviceURL,
                form: {'': ''},
                headers: {authorization: ''}
            });
        });
    }
}

Second, in the other file in which you invoke the function, you will have to now pass a callback function.

options = consulQuery('auth', (err, response) => {
if(err){
console.log(err)
}
console.log(response)

});
lrossy
  • 533
  • 3
  • 10
  • Just gave that a try and using your code I get undefined as well for the options. Also seems like my first one is not running but instead only the one in my `setInterval` is. – joshk132 Feb 09 '19 at 14:01
  • When I call it in my routes file I am seeing it is a function but it will not run. – joshk132 Feb 09 '19 at 14:33