Question: Node.js - Passing multiple objects to same EJS file

Question

Node.js - Passing multiple objects to same EJS file

Answers 1
Added at 2016-12-26 21:12
Tags
Question

I have multiple MySQL query results where I render the first and make callable the rest ones to a single EJS file (/data) as objects.

I render only the first query results (obj) and then I make the rest callable to the EJS (rsum_total_sales & rsum_count_active)

It seems that the first time that I load the EJS file I get frontend 500 errors like

   rsum_total_sales is not defined

but when I reload the browser I get the EJS to loading fine, showing all the needed results that got from the route file.

Weird thing that even the first time, in console.log() I see that all three query results have been put in the objects I made, however they cannot be yet callable to the EJS except the first ones which renders directly to it.

From the EJS error I can see that it passes the first connection.query results (obj) which is rendered but not the rest two (rsum_total_sales & sum_count_active) which I just make their objects callable until I reload the browser.

route file

var obj = {};
var qsum_total_sales = 'SELECT SUM (total_price) AS s_total_price FROM myrecords'; 
var qsum_count_active = 'SELECT COUNT (*) AS s_count_active FROM myrecords WHERE NOT status = "canceled" ';
var qdata = 'SELECT * FROM myrecords';

router.get('/data', function(req, res){
    connection.query(qdata, function(err, result) {
        if(err){
            throw err;
           } else {
                obj = {print: result};
                res.render('data', obj);
                console.log(obj);
        }
    });

   connection.query(qsum_total_sales, function(err, rows, result) {
       if(err){
           throw err;
       } else {
           rsum_total_sales = JSON.parse(rows[0].s_total_price).toFixed(2);
           console.log(rsum_total_sales); 
           //First time prints result but it can't be called to EJS until reloading EJS
       }
   });

  connection.query(qsum_count_active, function(err, rows, result) {
       if(err){
           throw err;
       } else {
           rsum_count_active = JSON.parse(rows[0].s_count_active);
           console.log(rsum_count_active);  
           //First time prints result but it can't be called to EJS until reloading EJS
       }
   }); 
});

EJS file

<tbody>
    <% print.forEach(function (datatable) { %>
        <tr>
             <td><%= datatable.id %></td
             <td><%= datatable.full_name %></td>
             //rest of loop
         </tr>                              
        <% }) %>
</tbody>
    // some html code
<h4>Total sales sum is: <%- rsum_total_sales %></h4>
<h4>Total active records are: <%- rsum_count_active %></h4>

Frontend Error (only when it is the 1st time that EJS loads to the browser)

ReferenceError: C:\NodeJS\CRUD-1\views\data.ejs:39
    37|         </table>
    38|         <hr/>
>>  39|         <h4>Total sales sum is: <%- rsum_total_sales %></h4>
    40|         <h4>Total active records are: <%- rsum_count_active %></h4>

rsum_total_sales is not defined
at eval (eval at <anonymous> (C:\NodeJS\CRUD-1\node_modules\ejs\lib\ejs.js:481:12),
<anonymous>:47:17)
at returnedFn (C:\NodeJS\CRUD-1\node_modules\ejs\lib\ejs.js:512:17)
at View.exports.renderFile [as engine] (C:\NodeJS\CRUD- 1\node_modules\ejs\lib\ejs.js:364:31)
at View.render (C:\NodeJS\CRUD-1\node_modules\express\lib\view.js:126:8)
at tryRender (C:\NodeJS\CRUD-1\node_modules\express\lib\application.js:639:10)
at EventEmitter.render (C:\NodeJS\CRUD-1\node_modules\express\lib\application.js:591:3)
at ServerResponse.render (C:\NodeJS\CRUD-1\node_modules\express\lib\response.js:960:7)
at Query._callback (C:\NodeJS\CRUD-1\routes\data.js:36:17)
at Query.Sequence.end (C:\NodeJS\CRUD-1\node_modules\mysql\lib\protocol\sequences\Sequence.js:86:24)
at Query._handleFinalResultPacket (C:\NodeJS\CRUD-1\node_modules\mysql\lib\protocol\sequences\Query.js:144:8)
Answers
nr: #1 dodano: 2016-12-27 04:12

I don't see where are you sending rsum_total_sales and rsum_count_active to the front-end. Also you are running the 3 queries separately, second one will not wait for the first one to finish and similarly third one will not wait for the second one to finish.

As soon as the first one finishes it will send the data(obj) back to the client(front-end) and wont wait for the second and third query to finish, hence you cant know if you got all the data in front-end.

You should do the second in the callback of the first and third in the callback of second and send the obj to front-end after successful completion of third query. This way you can ensure that all the data is going to front-end.

Try this:

var obj = {};
var qsum_total_sales = 'SELECT SUM (total_price) AS s_total_price FROM myrecords';
var qsum_count_active = 'SELECT COUNT (*) AS s_count_active FROM myrecords WHERE NOT status = "canceled" ';
var qdata = 'SELECT * FROM myrecords';

router.get('/data', function(req, res) {
  connection.query(qdata, function(err, result) {
    if (err) {
      throw err;
    } else {
      obj = {
        print: result
      };

      console.log(obj);
      connection.query(qsum_total_sales, function(err, rows, result1) {
        if (err) {
          throw err;
        } else {
          rsum_total_sales = JSON.parse(rows[0].s_total_price).toFixed(2);
          console.log(rsum_total_sales);


          connection.query(qsum_count_active, function(err, rows2, result2) {
            if (err) {
              throw err;
            } else {
              rsum_count_active = JSON.parse(rows2[0].s_count_active);
              console.log(rsum_count_active);

              //After successful completion of all 3 queries send data back to cliend(front-end)
              //its better to create new obj everytime and send it
              //store all the data in obj and send back to client
              var obj = {};
              obj.print = result;
              obj.rsum_count_active = rsum_count_active;
              obj.rsum_total_sales = rsum_total_sales;
              res.render('data', obj);
            }
          });
        }
      });
    }
  });

});
Source Show
◀ Wstecz