1

I have an express app where I'm calling a function with an API call. The problem I'm having is getting the response from the API call out of the function and back to the main router. I know this may have to do with the code being processed asynchronously but I can't figure out a way around the issue.

/* GET funnel page. */
router.get('/funnel', function(req, res, next) {
var score = 'test2';    
score = GetQuery('Bars');
  res.render('funnel', {title: score});
});

function GetQuery(query) {
  var test = 'test3';
  factual.get('/t/places-us', {q:query,limit: 1, filters:{"$and":[{"region":{"$eq":"NY"}},{"locality":"pittsford"}]}}, function (error, res) {
   test = res.data[0].email;
  });
return test;
}
1
  • 1
    Async, async, async. This is one of more common issues with people coming up to speed on node.js development. factual.get() looks like it's an asynchronous function. That means that it returns its value by calling the callback sometime LATER. Thus GetQuery() has already returned before the value of test has even been set. As such, you cannot return the value from GetQuery(). You must return the result in an async-compatible manner which means using a promise or a callback. Commented Aug 15, 2015 at 6:16

2 Answers 2

3

You're right it does have something to do with asynchrony. The problem is that the API call does not block so you return immediately without reassigning the value. The simplest way to solve this would be to use a callback i.e.

/* GET funnel page. */
router.get('/funnel', function(req, res, next) {
  var score = 'test2';    
  GetQuery('Bars', function(err, score) {
    res.render('funnel', {title : score});
  });
});

function GetQuery(query, cb) {
  factual.get('/t/places-us', {q:query,limit: 1, filters:{"$and":[{"region":{"$eq":"NY"}},{"locality":"pittsford"}]}}, function (error, res) {
   cb(error, res.data[0].email);
  });
}

Another option would be to use a Promise or something like RxJS. Which would both let you use a more fluent style for your code:

Promise:

/* GET funnel page. */
router.get('/funnel', function(req, res, next) {
  var score = 'test2';    
  GetQuery('Bars').then(function(score) {
    res.render('funnel', {title : score});
  });
});

var getQuery = Promise.denodify(factual.get);

function GetQuery(query) {
  return getQuery('/t/places-us', /*Query parameters*/).then(function (res) {
   return res.data[0].email;
  });
}

RxJS

/* GET funnel page. */
router.get('/funnel', function(req, res, next) {
  var score = 'test2';    
  GetQuery('Bars').subscribe(function(score) {
    res.render('funnel', {title : score});
  });
});

var getQuery = Rx.Observable.fromNodeCallback(factual.get, null, 
                             function(res) { 
                               return res.data[0].email; 
                             });

function GetQuery(query) {
  return getQuery('/t/places-us', /*Query*/);
}
Sign up to request clarification or add additional context in comments.

Comments

0

Use callback

GetQuery('Bars', function(err,result){
    res.render('funnel', {title: score});    
});
function GetQuery(query,callback) {
    var test = 'test3';
    factual.get('/t/places-us', {q:query,limit: 1, filters:{"$and":[{"region":{"$eq":"NY"}},{"locality":"pittsford"}]}}, function (error, res) {
        callback(error,es.data[0].email);
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.