Pergunta

I need to return a value from a function, which gets its information from a query. I'm having some trouble passing information from the query's anonymous function to the container function.

I tried creating an array in a higher scope (the container function) and having the query function write to the array per result, but that didn't seem to work. I also tried passing the array into the query's anonymous function. That did not appear to work either.


Here's my function (executed within Node):

function retrieveSales(connection,timeFrame) {

    var sales = new Array();

    connection.query('select * from sales_entries where date BETWEEN ? AND ?',
    timeFrame,

    function (err, rows, fields, sales) {

        if (err) return callback(new Error('Failed to connect'), null);

        connection.end();

        for (x = 0; x < rows.length; x++) {
            sales.push(rows[x]);
        }

    });

    console.log('Sales Returned: ' + JSON.stringify(sales, null, 4));

    return sales;

}

which result in 'cannot call method 'push' of undefined.

How should I properly write to the sales array so that I can return it with retrieveSales()?

Foi útil?

Solução

You are dealing with JavaScript's beautiful asynchronous-ness-icity. You are are trying to return out of an asynchronous method. Try to brush up on how asynchronous programming works, and it'll make your life much, much easier; it isn't very hard, just different. Check out this code sample, hopefully it can get you up and going.

// use this as your callback to handle the results from connection.query()
function sales_cb(rows) {
  var sales = [];
  for (x = 0; x < rows.length; x++) {
    sales.push(rows[x]);
  }
  console.log('Sales Returned: ' + JSON.stringify(sales, null, 4));
}

function retrieveSales(connection, timeFrame) {
  // connection.query() is asynchronous - interact with it accordingly
  connection.query('select * from sales_entries where date BETWEEN ? AND ?', timeFrame,
    function (err, rows, fields, sales) {
      if (err) {
        callback(new Error('Failed to connect'), null);
      } else {
        // invoke sales_cb(sales) once the for loop is done
        sales_cb(rows);
      }
    });
}

Let me know if this helps :)

Outras dicas

Using:

https://github.com/kriskowal/q

Here is how to do it with a promise:

var q = require('q');


function retrieveSales(connection,timeFrame) {

  var sales = new Array();
  var deferred = q.defer();

  connection.query('select * from sales_entries where date BETWEEN ? AND ?',
     timeFrame,

     function (err, rows, fields) {

     if (err) return callback(new Error('Failed to connect'), null);

     connection.end();

      for (x = 0; x < rows.length; x++) {
          sales.push(rows[x]);
      }

      deferred.resolve(sales);
  });

  deferred.then(function(salesback) {
    console.log('Sales Returned: ' + JSON.stringify(salesback, null, 4));
  }

  // added bonus -- the calling function can also use the promise
  return deferred;

}

more info: http://howtonode.org/promises

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top