I am writing a chat on NodeJS and Socket.IO and displaying messages in json on the page http://127.0.0.1/messages

  1. I make a request for messages from the Mysql database and get:

    id (message ID), user_id (ID of the message author), msg (message text)

  2. After with the author's id, I get his avatar and name and shove everything into one object.

Code:

  app.get('/messages', function(req, res) { var messages = {}; db.getConnection(function(err, connection) { connection.query('SELECT * FROM `chat` LIMIT 0, 30', function(err, rows) { res.setHeader("Access-Control-Allow-Origin", "*"); for (var prop in rows) { connection.query('SELECT user_name, user_photo FROM `users` WHERE user_id = "'+rows[prop]['user_id']+'"', function (error, result) { messages[rows[prop]['id']] = {user_id: rows[prop]['user_id'], msg: rows[prop]['msg'], info: result}; }); } res.send(JSON.stringify(messages)); connection.release(); }); }); }); 

But in object messages nothing is written and I display on page {}

  • Another question about the misunderstanding of asynchronous logic. - Dmitriy Simushev

1 answer 1

The actions you do in for are asynchronous. As a result, the request is sent before all these actions are completed.

The solution to the problem is very simple: you need to first execute each of the requests in for and only when all these requests are executed will it be answered.


There are a large number of implementations of asynchronous cycles. For example, you can use the async library:

 var messages = {} async.forEachOf(rows, function(row, prop, cb) { connection.query('SELECT user_name, user_photo FROM `users` WHERE user_id = "'+ row['user_id']+'"', function (error, result) { if (error) { // Не удалось выполнить запрос return cb(error); } messages[row['id']] = { user_id: row['user_id'], msg: row['msg'], info: result }; cb(); }); }, function(err) { connection.release(); if (err) { // Вам нужно как-то обработать ошибку. return; } res.send(JSON.stringify(messages)); }); 
  • Thanks for the help! :) - Red Woolf