twigjs / twig.js

JS implementation of the Twig Templating Language
BSD 2-Clause "Simplified" License
1.88k stars 275 forks source link

no XMLHTTPRequest implementation #273

Closed staminna closed 8 years ago

staminna commented 8 years ago

Hi

Can someone post a example for a custom XMLHTTPRequest implementation that works with the provided wiki documentation?

I get a error "TwigException: Unsupported platform: Unable to do remote requests because there is no XMLHTTPRequest implementation"

code for app.js:

var template = twig({ id: "posts", href: "templates/posts.twig", // for this example we'll block until the template is loaded async: false

// The default is to load asynchronously, and call the load function 
//   when the template is loaded.

// load: function(template) { }

});

posts = { ... }; // data from somewhere like an AJAX callback

// render the template var postsHTML = twig({ ref: "posts" }).render(posts);

// Display the rendered template document.getElementById("posts").innerHTML = postsHTML;

Thank you.

createvibe commented 8 years ago

https://plnkr.co/edit/Y4fD7x7S0finKw5Fmsug

plepe commented 8 years ago

@staminna Has your question been answered sufficiently?

staminna commented 8 years ago

I can see that it works properly on the browser side, however I couldn't get this to work on a stream of objects ("posts") from nodejs from the console into the template. I'm still not clear about how to achieve this.

` var Twig = require('twig'), twig = Twig.twig; // Render function var express = require('express'), app = express(); var http = require('http');

exampleApi.search('stuff', function(err, res) {

  app.get('/', function(req, res){

    for(i=0; i < Object.keys(dataObject).length; i++) {
      console.log(dataObject.values);
      res.render('index.twig', {
        information : dataObject[array]
      });
  };

});
app.listen(9999);

}); `

`

How can I create a list from the nodejs objects I am looking at in the browser console?

` As soon as I refresh or request the page on localhost:9999 , it crashes node:

_http_outgoing.js:335 throw new Error('Can\'t set headers after they are sent.'); ^

Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11) at ServerResponse.header (/node_modules/express/lib/response.js:718:10) at ServerResponse.send (/node_modules/express/lib/response.js:163:12) at done (/node_modules/express/lib/response.js:957:10) at params.load (/node_modules/twig/twig.min.js:10:29427) at loadTemplateFn (/node_modules/twig/twig.min.js:8:14957) at FSReqWrap.readFileAfterClose as oncomplete

createvibe commented 8 years ago

res.render without a callback will invoke res.send, which will send the HTTP response, including headers. In your example, you are calling res.render for each key in your dataObject, so on the second iteration, you would receive this error.

See, http://expressjs.com/en/api.html#res.render and http://expressjs.com/en/api.html#res.send

Can you explain a little better what you're trying to accomplish? Maybe I can write a runnable example for you.

staminna commented 8 years ago

Thank you for your input, the errors are gone, but I hope I can explain this better. what I am trying to do is having a template that is dynamically updating a stream of data as soon as there is new data in dataObject object. This data is coming from a node.js module that pulls data from a third party API

client.stream('statuses/filter', {track: 'gravitational waves'}, function(stream) {
  stream.on('data', function(tweet) {
//  console.log(tweet);  // live data object with all the tweets

  var twittpic = 'default.jpg';

  if (typeof tweet.entities.media != 'undefined'){
   twittpic = tweet.entities.media[0].media_url;  // map and send image to twig.js
  }
   console.log(twittpic);  // keeps printing different pictures from different tweets.
   number = Object.keys(tweet).length;  // so I know how many different tweets available

  app.get('/', function(req, res){  // it looks like it only runs once.
        res.render('index.twig', {title: tweet, picture: twittpic, number:number});
      });

  });

  stream.on('error', function(error) {
    throw error;
  });
});

  app.listen(9999);

index.twig:

`{% for i in 1..number %} {{dump(picture)}}

{{title.text}}

  <img class="images" src="{{picture}}" alt="wall feed pictures" />

{% endfor %}`

I can see the pictures and title, but it keeps repeating the same picture and tweets.

createvibe commented 8 years ago

Correct me if I'm wrong, but It seems like you are trying to push new data from the stream directly to the client. If this is true, you should use something like socket.io.

You seem to be defining a GET route in express, so when you navigate to '/' (index) it will render index.twig with the last known tweet data (from the closure), but it wouldn't actually send new tweets to the client.

dave-irvine commented 8 years ago

@createvibe is correct, to achieve what you want you need a permanent socketed connection between server and client, so socket.io would do this.

Closing as you haven't replied in a long time.