Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to return data from client.query cb event to function? #81

Closed
Mathiu opened this issue Jun 15, 2011 · 13 comments
Closed

how to return data from client.query cb event to function? #81

Mathiu opened this issue Jun 15, 2011 · 13 comments

Comments

@Mathiu
Copy link

Mathiu commented Jun 15, 2011

Hello everyone, i have started my journey with nodejs a couple weeks ago and i have a problem, dont know what exacly is it, issue or what, anyways, I have a function in my lib file getUserData to retrive user data from mysql:

lib.getUserData = function(userId) {
var resultUser = {};
mysqlc.query("SELECT * FROM za_users WHERE id = ?", [userId],
function(err, results) {
if (err) {
throw err;
}
resultUser = results;
});
return resultUser;
}

and when i call that function from my main file i always gets an empty object. I tried a lot of ways but none of them works :/
I know that i can put client.query to my main file without function but i want to have a clean code.

I tried return reuslts to this.variable, i've created function to retrive last results, and i spend tree days on this, and i'am despred. So i really be greatful for any advice here.

@Mathiu
Copy link
Author

Mathiu commented Jun 16, 2011

OK, i'am sorry i didnt know about assynchronous calls, but how can i use this results data? Is one and only way is to use some function inside function(err, results) { } and then execute some instructions?

Sorry for my ignorance, i'am kind of newbie in js, and my english, i'am from Poland.

@davide-scalzo
Copy link

I had the same problem, but then I read more in detail the documentation.
that's what I understood:
The client.query returns a Query object that has some events, row, field, end and so on... so if you attach an event listener like

sqlResult = sql.query("SELECT * FROM za_users WHERE id = ?", [userId]);
sqlResult.on('row', function(row) {
  //assuming we are routing a get request, let's publish our result on the browser
  res.write(row.name);
});

What I still need to understand is how to put all this data into a variable that I can manage through the JADE engine :S

@mscdex
Copy link
Contributor

mscdex commented Aug 12, 2011

@davodesign84

If you want all of the results at once instead one row at a time, pass in a callback to query(), like so:

sql.query("SELECT * FROM za_users WHERE id = ?", [userId], function(err, rows) {
  // check if err is set first
  // then pass rows to your template
  // where rows is an array of the records returned from the server
  //   i.e.: rows[0].name, rows[0].foo; rows[1].name, rows[1].foo
});

@davide-scalzo
Copy link

That works but then we go back to the question that Mathiu was asking, so how do retrieve that array from the callback.

Which is also not a good idea as ideally we should try to keep everything async as possible!
At least to my understanding..

@mscdex
Copy link
Contributor

mscdex commented Aug 12, 2011

@davodesign84

In his case, you'd have to pass in a callback instead of using the return value of the function because the query is async:

lib.getUserData = function(userId, cb) {
  mysqlc.query("SELECT * FROM za_users WHERE id = ?", [userId], 
    function(err, results) { 
      if (err)
        return cb(err);
      cb(undefined, results);
  });
}

// Usage:
lib.getUserData(1337, function(err, results) {
  // use results in your template if !err
});

@Mathiu
Copy link
Author

Mathiu commented Aug 12, 2011

At first very thanks for replies guys.

Your code seems great, but i cant check it right now and i will be able
after this weekend, so ill post are they enough for me.

2011/8/12 mscdex <
reply@reply.github.com>

@davodesign84

In his case, you'd have to pass in a callback instead of using the return
value of the function because the query is async:

lib.getUserData = function(userId, cb) {
 mysqlc.query("SELECT * FROM za_users WHERE id = ?", [userId],
   function(err, results) {
     if (err)
       return cb(err);
     cb(undefined, results);
 });
}

// Usage:
lib.getUserData(1337, function(err, results) {
 // use results in your template if !err
});

Reply to this email directly or view it on GitHub:
#81 (comment)

Pozdrawiam!
Mateusz Palaczyk :)
Dirt Arts CEO

@davide-scalzo
Copy link

cool I'll try that as well, seems easier than having a stream of data (guess that for that I need socket.io) and should be perfect for most application, thanks!

@bslayton
Copy link

@mscdex

I added a callback function, and I can do console.write(results) and it works. However I cannot do response.write the results.I am passing the response and request vars to my callback but it doesn't write to my screen. If I do console.write(response) it will give me the same data as if I were outside of my callback function.

Any idea on what to do?

@mscdex
Copy link
Contributor

mscdex commented Aug 30, 2011

@bslayton can you provide a gist of the code?

@arnoprinz
Copy link

I'm working on that interface-problem since i'm working with the mysql-database. The target is an web-application without mvc or something with magic. I'm using jade as template-engine, because i can use dynamic node-code and jquery + jquery-ui for dynamic html.

First of all you must have some rooting to handle the GET form web-client (i use meryl.js).
Jade has an option called locals to inject or interpolate the rendered jade-file.

it could be every-request-response-function with callback:

 .handle('GET /mypartial', function (req, resp) {
     mysqlc.query("SELECT * FROM za_users ", 

       // here begins the callback-function body, witch is drilled down
       // in the depths of the query

       function(err, rows) { 
         if (err) return cb(err);

         // this variables passes the result to jade 
         var elements= { datarows: rows }  
         var options = {locals:{elements:elements}};

         jade.renderFile(__dirname + '/forms/partial.jade', options, function(err, html){
           if (err) throw err;
              //console.log(html)
              resp.write(html);
              resp.end();         
         }); //render 



   });

 })



 partial.jade
 ============

 the code injection should report the transfered rows in the node-console

  - console.log('\n>>>> jade-partial <<<<\n') 
  - console.log('test locals, elements: ', elements)

@mscdex
Copy link
Contributor

mscdex commented Aug 31, 2011

What if you take out the jade rendering and try simply doing something like:

 .handle('GET /mypartial', function (req, resp) {
     mysqlc.query("SELECT * FROM za_users ", 

       // here begins the callback-function body, witch is drilled down
       // in the depths of the query

       function(err, rows) { 
         if (err) return cb(err);
         resp.end(JSON.stringify(rows));
   });
 })

If that works, then maybe it's jade-related and nothing to do with node-mysql?

@bslayton
Copy link

I figured out my problem. I have created my own mini framework for handling models and controllers. No views since this is housing an API. I couldn't do response.write in my controller when response.end() was in my main app.js file after I call my controller for some reason. It's like it was skipping it or something. No biggy, I just had to put my response.end() in my database callback in the controller.

@felixge
Copy link
Collaborator

felixge commented May 15, 2012

Closing this, seems resolved. Thanks @mscdex for providing your input.

@felixge felixge closed this as completed May 15, 2012
dveeden pushed a commit to dveeden/mysql that referenced this issue Jan 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

6 participants