ClientJade - Trouble executing jade.render() - node.js

I've run into a problem in the clientside code for a Node.js app I'm working on.
The idea behind this is to update the browser immediately as the socket receives an event.
This is the script block on the client side:
script(src='/scripts/jadeTemplate.js')
script(src='/socket.io/socket.io.js')
script(type='text/javascript')
var socket = io.connect();
socket.on('obj', function(obj) {
var newsItem = document.createElement("item");
jade.render(newsItem, 'objTemplate', { object: obj });
$('#newsfeed').prepend(newsItem);
alert(obj);
});
When the alert() is placed before the jade.render(), it alerts, but if inserted after, it doesn't execute (hence, I think it's a problem with the jade.render()).
This is objTemplate.jade, referred to in line 7:
p #{object}
// That's it.
And this is a relevant snippet from the app.js:
var server = dgram.createSocket('udp4');
server.bind(41234);
server.on('message', function(buf, rinfo) {
isOnline = true;
var message = buf.toString();
io.sockets.emit('obj', message);
});
UPDATE:
Here's a link to /public/scripts/jadeTemplate.js, which IMO is too long of a snippet for a question.
If I need to provide any more snippets or files let me know. :)

Your template doesn't want an attribute object, it wants obj. Try this:
socket.on('obj', function(obj) {
var newsItem = document.createElement("item");
jade.render(newsItem, 'objTemplate', { obj: obj }); // changed object to obj
$('#newsfeed').prepend(newsItem);
alert(obj);
});
http://jsfiddle.net/trevordixon/VeYBY/ shows it working. If you change the attribute back to object, you'll get a javascript error in the console.

Related

Changes don't occur because of node.js' asynchronicity

I'm a beginner at node js and I'm doing a simple project with pure node.js.
So here is my code:
if(req.url ==="/"&&req.method==="POST"){
let reqBody = "";
req.on('data', chunk=>{
reqBody += chunk.toString();
});
req.on("end", ()=>{
reqBody = reqBody.split("&");
for(let i=0; i<reqBody.length; i++){
reqBody[i]=reqBody[i].split("=");
reqBody[i] = reqBody[i][1];
};
//filter country
let countryFound;
if(reqBody[1].length>0){
let countryList = "";
let countryVal = [];
countryListStream = fs.createReadStream("./public/country.list.json", "UTF-8");
countryListStream.on("data", countryChunk=>{
countryList+=countryChunk;
countryChunk = JSON.parse(countryChunk);
countryFound = countryChunk.filter(elem=> elem["name"].toLowerCase()==reqBody[1].toLowerCase());
if(countryFound.length!==0){
countryListStream.destroy();
};
});
countryListStream.on("end", ()=>{
countryFound = "Not Found"
});
};
});
};
My problem is below "filter country" comment:
when I log the "countryFound" variable outside of the events of "countryListStream", it displays undefined.But when i log it inside of the events, it displays what I want. I think it's becaus of how node.js is made, but I don't know to continue my code if it's undefined.
I think that I need to include a code that waits until the variable is updated, and then it runs the rest.
I tried with this after the if statement, and it didn't fixed it:
if(countryFound!===undefined){
console.log(countryFound);
}
From looking at the documentation, calling countryStream.destroy() emits close and error events. So, it would make sense to add a handler to the close event where you can continue processing the values that you have assigned to those variables:
countryStream.on('close', () => {
console.log(countryFound) // should not be undefined now
// ...do something with your new values
});

Enter twice in socket.on event

I'm new to Angular and Node.js.
My code executes a socket.emit to a server side function and receives a response in the socket.on event ('listartists').
Unfortunately, he enters twice in this event and I do not understand why.
On the server side (app.js) I put logs and the function is called correctly once, but then it goes through the socket.on twice ('listartists').
Thank you all
var appAng = angular.module('appAng', []).controller('myCtrl', function($scope) {
socket.on('listartists', function(msg) {
// !!! enter twice this part of the code
var ClientMessage = JSON.parse(msg);
if (ClientMessage.ClientID == GetClientUniqueId()) {
var artistslist = JSON.parse(ClientMessage.Message);
$scope.$apply(function() {
var artistslist=JSON.parse(ClientMessage.Message);
$scope.artists = artistslist;
});
}
});
});
i modified my code as :
socket.on('listartists', function(msg){
var ClientMessage=JSON.parse(msg);
if (ClientMessage.ClientID== GetClientUniqueId())
{
console.log("Arriva Lista Artisti " + ClientMessage.ClientID);
var artistslist =JSON.parse(ClientMessage.Message);
$scope.artists = artistslist;
$scope.$apply( function(){});
}
});
Anyway if i remove $scope.$apply( function(){}); the socket.on event is called only once,
otherwise it passes twice from there.
I think the problem is the management of the SCOPE some idea?

waitforSelector function in casperjs

hello I am new to Casper and node
I am trying to run a code that scrpping data from a site
but WaitForselector function is not working correctly .
my code is
casper.waitForSelector('.searchAutoSuggstn', function() {
this.echo('Search auto suggestion.'); // this line is printing my console
var data = this.evaluate(function() {
var suggestions = [];
this.echo('Search auto suggestion data.'); //But this line is not printing my console
var element = $('.searchAutoSuggstn .suggestionsList_menu').find('.topProdhead_left').prevAll().filter(function() {
this.echo('omnitrack');
return $(this).data("omnitrack") ;
});
is any boddy can tell me whats the main problem ?
You can't call casper methods such as casper.echo() in casper.evaluate() since evaluate executes code in the context of the browser.
You could use console.log in the browser to output to the javascript console which you can then catch with the hook
casper.on("remote.messsage", function(msg){
// Do something
});

Mongoose Trying to open unclosed connection (callback hell)

I want to add a loop to the database records. But mongoose wrote that I did not close the open connection. Mongoose Trying to open unclosed connection. How to make the whole thing went in sync? Its callback hell in my code
app.get("/dobavit/", function(req, res) {
for(var i=50; i>0; i--)
{
InsertAXIXA("analitika",i,function(data){
});
}
res.end();
});
function InsertAXIXA(qwerty,page,callback){
mongoose.connect('mongodb://localhost/gazprom')
var parsedResults = [];
var req = request('http://xxx.ru/'+qwerty+"?page="+page, function (error, response, html) {
if (!error && response.statusCode == 200) {
// str = iconv.decode(html, 'utf-8');
var $ = cheerio.load(html);
$('.col-1 .col-first').each(function(i, element){
var buf = $(this);
var zagolovok = buf.children(0).children().children().eq(0).text();
var previewText = buf.children(2).children().eq(0).text();
var url = buf.children(0).children().children().eq(0).attr('href');
var picUrl = buf.children(1).children().eq(0).children().children().eq(0).attr('src');
var metadata = {
zagolovok:zagolovok,
previewText:previewText,
url:url,
typeOfnews:qwerty,
picUrl:picUrl,
qwerty:qwerty
};
var news =new News({
zagolovok: zagolovok,
previewText: previewText,
url:url,
picUrl:picUrl,
qwerty:qwerty
// created_at:Date.today()
});
news.save(function(err, news,affected){
});
parsedResults.push(metadata);
});
callback(parsedResults);
}
mongoose.connection.close()
});
You shouldn't actually need to open/close your connection on every request (see here for more about that).
Instead, you can just open your connection once when your app starts and then just let it close when the app closes.
If you leave the connection open, you can reuse the connections instead of wasting time/resources establishing a new one every time that function is called.
In my opinion, you are trying to create another connection without closing the current one. So, you might want to use:
createConnection() instead of connect().
In your case, it would look like this:
db = mongoose.createConnection('mongodb://localhost/mydb');
i was getting the same error today, the solution which i found is, we should not call the mongoose.connect function in loop or anywhere in the code which is being executed again and again.
so my example is, i was doing mongoose.connect on all request of app.
app.all("*",function(){
mongoose.connect();
})
Your code is somewhat similar to because in loop you are calling function and in function you are opening connection.
Thanks

http.Clientrequest.abort() ends program

I'm having some issues using Node.js as a http client against an existing long polling server. I'm using 'http' and 'events' as requires.
I've created a wrapper object that contains the logic for handling the http.clientrequest. Here's a simplified version of the code. It works exactly as expected. When I call EndMe it aborts the request as anticipated.
var http = require('http');
var events = require('events');
function lpTest(urlHost,urlPath){
this.options = {
host: urlHost,
port: 80,
path: urlPath,
method: 'GET'
};
var req = {};
events.EventEmitter.call(this);
}
lpTest.super_ = events.EventEmitter;
lpTest.prototype = Object.create(events.EventEmitter.prototype, {
constructor: {
value: lpTest,
enumerable: false
}
});
lpTest.prototype.getData = function getData(){
this.req = http.request(this.options, function(res){
var httpData = "";
res.on('data', function(chunk){
httpData += chunk;
});
res.on('end', function(){
this.emit('res_complete', httpData);
}
};
}
lpTest.prototype.EndMe = function EndMe(){
this.req.abort();
}
module.exports = lpTest;
Now I want to create a bunch of these objects and use them to long poll a bunch of URL's. So I create an object to contain them all, generate each object individually, initiate it, then store it in my containing object. This works a treat, all of the stored long-polling objects fire events and return the data as expected.
var lpObject = require('./lpTest.js');
var objWatchers = {};
function DoSomething(hostURL, hostPath){
var tempLP = new lpObject(hostURL,hostPath);
tempLP.on('res_complete', function(httpData){
console.log(httpData);
this.getData();
});
objWatchers[hosturl + hostPath] = tempLP;
}
DoSomething('firsturl.com','firstpath');
DoSomething('secondurl.com','secondpath);
objWatchers['firsturl.com' + 'firstpath'].getData();
objWatchers['secondurl.com' + 'secondpath'].getData();
Now here's where it fails... I want to be able to stop a long-polling object while leaving the rest going. So naturally I try adding:
objWatchers['firsturl.com' + 'firstpath'].EndMe();
But this causes the entire node execution to cease and return me to the command line. All of the remaining long-polling objects, that are happily doing what they're supposed to do, suddenly stop.
Any ideas?
Could it have something to do with the fact that you are only calling getData() when the data is being returned?
Fixed code:
function DoSomething(hostURL, hostPath){
var tempLP = new lpObject(hostURL,hostPath);
tempLP.on('res_complete', function(httpData){
console.log(httpData);
});
tempLP.getData();
objWatchers[hosturl + hostPath] = tempLP;
}
I have seemingly solved this, although I'm note entirely happy with how it works:
var timeout = setTimeout(function(){
objWatchers['firsturl.com' + 'firstpath'].EndMe();
}, 100);
By calling the closing function on the object after a delay I seem to be able to preserve the program execution. Not exactly ideal, but I'll take it! If anyone can offer a better method please feel free to let me know :)

Resources