javascript - How to render rest api call in node.js with express and handlebar or other template engine? -


use case

using node.js, express , template engine handlebars query rest apis wordpress , couchdb , render results.

i have come far

var https = require('https');  var express = require('express'); var handlebars = require('express-handlebars')         .create({ defaultlayout:'main' });  var app = express(); app.engine('handlebars', handlebars.engine); app.set('view engine', 'handlebars'); app.set('port', process.env.port || 3000); app.set('ip', process.env.ip);  var options = {   hostname: 'public-api.wordpress.com',   path: '/rest/v1.1/sites/somesite.wordpress.com/posts/16',   method: 'get' };  app.get('/test', function(req, res) {   https.request(options, function(restres) {     console.log('status: ' + restres.statuscode);     res.render('home', { "title": "test" }); // code works.     restres.on('data', function (jsonresult) { //      res.render('home', { "title": "test" }); code (after removing line above) not work.       console.log('body: ' + jsonresult);     });   }).end(); });  app.listen(app.get('port'), app.get('ip'), function(){   console.log( 'express started on http://' + app.get('ip') + ": " +     app.get('port') + '; press ctrl-c terminate.' ); }); 

this code works , jsonresult show correcty @ console. moving line res.render('home', { "title": "test" }); inside restres.on('data', function (jsonresult) callback throws error.

error: can't set headers after sent.     @ serverresponse.outgoingmessage.setheader (_http_outgoing.js:331:11)     @ serverresponse.header (/home/ubuntu/workspace/node_modules/express/lib/response.js:718:10)     @ serverresponse.send (/home/ubuntu/workspace/node_modules/express/lib/response.js:163:12)     @ res.render.done (/home/ubuntu/workspace/node_modules/express/lib/response.js:957:10)     @ immediate._onimmediate (/home/ubuntu/workspace/node_modules/express-handlebars/lib/utils.js:26:13)     @ processimmediate [as _immediatecallback] (timers.js:374:17) 

do oversee obvious error? how right way?

the error self-explanatory, cannot set header when response sent. error happen due following

cause 1

the following fails because try send response more once.

//the following lines send response  res.render('home', { "title": "test" }); // code works.   restres.on('data', function (jsonresult) { //you have send response above, hence error res.render('home', { "title": "test" }); code (after removing line above) not work.   console.log('body: ' + jsonresult); }); 

cause 2

this fails , shows error because, .on('data') called more once (depending on size of response) , because data returned in chunks hence, trying res.render multiple times.

restres.on('data', function (jsonresult) {    res.render('home', { "title": "test" });     console.log('body: ' + jsonresult); }); 

possible solution

you need use .on('data') receive chunks , build entire response here , use .on('end') res.render complete response. follow:

var body = ''; //use chunks build whole response body variable restres.on('data', function (chunk) {    body += chunk;  });  //this called when request finished , response returned //hence, use constructed body string parse json , return restres.on('end', function () {    console.log('whole response > ' + body);     var jsonobject = json.parse(body);    res.render('home', {data:jsonobject});     //in view use data json object. }); 

another possible solution rather concatenating chunks returned .on('data'), can push them in array , in .on('end') join array elements construct response body , parse json , return it. sample below:

var body = []; restres.on('data', function(chunk) {   body.push(chunk); });  restres.on('end', function() {   //joined chunks    var result = json.parse(data.join(''))   res.render('home', {data: result});  }); 

Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -