Javascript: return value of variable outside of callback function

I have a very specific question and hopefully someone can lend me a hand. I'm pretty green when it comes to Javascript a lot more when it comes to NodeJS.

I am using lodash

_.forIn

functionality to move and add to an object that is inside an array. It all looks something like this:

[ 
  { id: 20,
    keywords: 'shirts'
  },
  { id: 18,
    keywords: 'shoes'
  } 
]

      

Basically it is a list of keywords stored in db elasticsearch. I am trying to find a way to add to this object a counter of the number of results these keywords will return.

This score will be obtained from the elasticsearch setup we use to find our product database.

The result I would like to get would be something like this:

[ 
  { id: 20,
    keywords: 'shirts',
    count: 4
  },
  { id: 18,
    keywords: 'shoes',
    count: 15
  } 
]

      

This is the code I have right now:

function get_list( data ) {

  var list_data = data;
  var list = _.forIn( data, function( item, n, list_data ) {
    get_count( item, function( count_number ) {
      list_data[n].count = count_number;
    })
  });
  console.log( list, list_data );
}

function get_count( item, callback ) {

  var query = { // elasticsearch query here };  

  // elasticsearch query here, that returns the count in a callback
  es.count( query, function(count_number) { callback(count_number) } );
} 

      

When I run this, the console will show an immutable array. I have checked all returned data for each function, everything is checked. I just can not get the data directly to any list

or list_data

.

PS. This is not my actual code, but this is pretty much the gist of it, so there might be some typos.

Also, list

and list_data

is the result of my trying to figure out how it works. I've tried reading about how JS callbacks work, but nothing I've seen seems to be able to help me with my problem.

+3


source to share


1 answer


You can check the object list_data

only after completing all callbacks

.

If you want to check that your function is get_count

working, you can move the console.log inside callback

, this will result in multiple logs list_data

in the console.

function get_list( data ) {

  var list_data = data;
  var list = _.forIn( data, function( item, n, list_data ) {
    get_count( item, function( count_number ) {
      list_data[n].count = count_number;
      console.log( list, list_data );
    })
  });

}

function get_count( item, callback ) {

  var query = { // elasticsearch query here };  

  // elasticsearch query here, that returns the count in a callback
  es.count( query, function(count_number) { callback(count_number) } );
} 

      

To do this, I recommend using a module async

with which it is quite convenient to handle asynchronous calls like yours.



Here is a link to the module so you can start using it: https://github.com/caolan/async

This is how I could implement the module async

in our case:

var async = require('async');

function get_list(data) {

    var list_data = data;
    //Transform all the list_data objects adding the count prop.
    async.map(list_data, get_count, function(err, results) {
        console.log(results);
    });
}

function get_count(item, callback) {
    var query = { // elasticsearch query here 
    };
    // elasticsearch query here, that returns the count in a callback
    es.count(query, function(count_number) {
        //add the new prop to the item
        item.count = count_number;
        //return the transformed object
        callback(null, item);
    });
}

      

+3


source







All Articles