2016-12-26 2 views
1

Ich habe mehrere MySQL-Abfrage-Ergebnisse, wo ich die erste rendern und die restlichen zu einer einzigen EJS-Datei (/ Daten) als Objekte aufrufbar machen.Node.js - Mehrere Objekte an die gleiche EJS-Datei übergeben

mache ich nur die ersten Abfrageergebnisse (obj) und dann mache ich den Rest aufrufbar zum EJS (rsum_total_sales & rsum_count_active)

Es scheint, dass das erste Mal, dass ich laden die EJS-Datei ich Frontend 500 Fehler wie

rsum_total_sales is not defined 

aber wenn ich den Browser neu zu laden erhalte ich die EJS zu loa in Ordnung, zeigt alle benötigten Ergebnisse aus der Routendatei.

Seltsame Sache, dass sogar das erste Mal, in console.log() sehe ich, dass alle drei Abfrageergebnisse in die Objekte, die ich gemacht habe, aber sie können noch nicht aufrufbar sein, die EJS außer den ersten, die direkt rendert zu ihm.

Vom EJS Fehler kann ich sehen, dass es die ersten connection.query Ergebnisse (obj) passiert, die gemacht wird, aber nicht der Rest zwei (rsum_total_sales & sum_count_active), die ich ihre Objekte machen aufrufbar nur, bis ich den Browser neu zu laden.

Routendatei

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 Datei

<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 Fehler (nur, wenn es das erste Mal ist, dass EJS Lasten an den 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) 
+1

ich sehe nicht, wo Sie senden 'rsum_total_sales' und' rsum_count_active' zum Frontend. –

Antwort

1

Ich sehe nicht, wohin senden Sie rsum_total_sales und rsum_count_active an das Front-End. Auch Sie laufen die 3 queries separat, second man wird nicht auf die first One zu Ende und in ähnlicher Weise warten third nicht auf die zweite zu beenden.

Sobald der erste abgeschlossen werden die Daten (obj) zurück zum client(front-end) und wird nicht für die second und thirdquery, man kann also beenden warten senden, wenn Sie die data in front-end alle haben.

Sie sollten die zweite im Rückruf des ersten und dritten im Rückruf der Sekunde tun und das obj zum Front-End nach erfolgreicher Beendigung der dritten Abfrage senden. Auf diese Weise können Sie sicherstellen, dass alle Daten im Front-End-Format vorliegen.

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); 
      } 
      }); 
     } 
     }); 
    } 
    }); 

}); 
+0

Das war sehr klar und logisch erklärt und funktioniert tatsächlich. Wenn es sich um ein Illustrationskonzept handelt, hat es mir den Kopf geöffnet.Es zeigt jedoch die ersten Symptome der sogenannten "Callback-Hölle" oder "Berg der Verdammnis". Stellen Sie sich vor, dass es dort irgendwann 5 oder 10 verschiedene Abfragen geben muss, deren Ergebnisse in derselben EJS-Datei gerendert werden. – Vasikos

+1

In diesem Fall können Sie 'Versprechen' anstelle von' Rückrufe' verwenden und Sie müssen sich nicht mit dem Problem der 'Rückruf-Hölle' beschäftigen. –

+0

Ich akzeptiere Ihre Antwort, weil auf ihre eigene Art (mit 'callbacks ** statt ** Versprechen ') half, eine Lösung für mein Problem zu bekommen, zumindest für den Moment, wo ich nur ein paar Fragen habe. Ich werde sicherlich versuchen, dies in den nächsten Tagen in "Verheißungs" -Methode umzuwandeln. – Vasikos

Verwandte Themen