Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knex select() returns before completing query in javascript

I have a function like this:

function get_projects() {
    var project_names=[];
    knex('projects').select('name').then(function (a) { 
        project_names.push(a);
    })
    return project_names;
}

This function executes the return statement return project_names; before completing project_names.push(a) statement and what I get after calling this function is an empty array, even though my db has results (I can see this if i log within the function a())

like image 818
user1896766 Avatar asked Dec 16 '13 05:12

user1896766


People also ask

What does KNEX Select Return?

And note: The return knex( returns the Promise object to the caller, and the return dataArr returns the value to the caller's .

What does KNEX where return?

Knex returns an array for all queries, even if there is only one row returned. The name of the user can be accessed from user[0] .

What is promise in knex?

Promises. Promises are the preferred way of dealing with queries in knex, as they allow you to return values from a fulfillment handler, which in turn become the value of the promise. The main benefit of promises are the ability to catch thrown errors without crashing the node app, making your code behave like a .

Is KNEX an ORM?

Sequelize is an ORM that includes some query builder stuff; Knex is just a query builder, not an ORM.


2 Answers

knex select() returns a promise so that you can continue the flow within then() function.

knex('projects').select('name').then(function(projectNames){
    //do something here
    console.log(projectNames);
});
like image 177
Dewey Avatar answered Sep 21 '22 12:09

Dewey


Nodejs is asynchronous, so as soon as your line knex('projects').select('name').then... is executed, the line `return project_names;' is run. As you have found out, it didn't wait until it was filled with values!

The standard "return" at the end of the methods isn't a good programming style for Nodejs, which is event based. It has its place, but more common is a callback approach. Consider reading some tutorials on this new approach (I like this one)

You might change your current code to something like:

function print_project_names() {
  get_projects( function(names){
    for( var i = 0; i < names.length; i++ )
    {
      console.log(names[i]+'\n');
    } 
  });
}

function get_projects( callback ) {
  var project_names=[];
  knex('projects').select('name').then(function (a) { 
     project_names.push(a);
     callback(project_names);
  })
}

NOTE: This is not optimized code

Here, when you want to print the project names (unsure your real goal), you are passing an actual function definition, as the "callback", into "get_projects". As the events fire, once the results are pushed into the project names, the callback is called with your new list.

like image 35
clay Avatar answered Sep 18 '22 12:09

clay