Here is my code i am facing issue in my get function where i write my code in forEach loop it gave an error of quotation(Unterminated String Literal).
var express = require('express');
var app = express();
var dataFile = require('./data/friend.json');
app.set('port', process.env.PORT || 5000);
app.get("/" , function(req , res ){
var data = '';
dataFile.friends.forEach(function(item){
data +='
<div>
<li>
<h1>${item.name}</h1>
<h2>${item.Class}</h2>
</li>
</div>';
});
res.send("Welcome");
});
app.listen(app.get('port') , function (err){
console.log("Server is running at "+ app.get('port'));
});
You can not have line breaks in JavaScript strings without concatenating or "escaping" them, unless using template literals (using the back-tick).
There are three ways to go about doing this.
Concatenation:
dataFile.friends.forEach(function(item){
data +='<div>'+
'<li>' +
'<h1>${item.name}</h1>' +
'<h2>${item.Class}</h2>' +
'</li>' +
'</div>';
});
Escaping Line Breaks:
dataFile.friends.forEach(function(item){
data +='<div>\
<li>\
<h1>${item.name}</h1>\
<h2>${item.Class}</h2>\
</li>\
</div>';
});
Template Literals:
dataFile.friends.forEach(function(item){
data +=`<div>
<li>
<h1>${item.name}</h1>
<h2>${item.Class}</h2>
</li>
</div>`;
});
Reference: SyntaxError: unterminated string literal
** It is also important to note that creating a string of elements may not instantiate them in to the DOM correctly. This will cause JavaScript to be unable to interact with these elements. DigitalOcean has a tutorial on this.
Alternatively, you can make use of template literals as mentioned above and available in the above reference link, this will instantiate elements inside the DOM.
Related
So I tested my scraping on a static HTML file before adding it to my Node app.
The problem is that it's not returning all the rows.
On the site:
$('#sport tr').length
//Returns 13
In Cheerio:
$('#sport tr').length
//Returns 2
I'm stumped, here is the code I'm using. I've contained the URL as proof, so you can visit it yourself if you wish.
I'm suspecting it's something to do with var $ = cheerio.load(html); however I'm not experienced in Cheerio to say outright that's the problem.
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/scrape', function(req, res){
var url = 'http://www.olbg.com/football.php';
var json = [];
request(url, function(error, response, html){
if(!error){
var $ = cheerio.load(html);
console.log($('#sport tr').length);
var headers = [];
$('#sport tr th').each(function(i, th) {
var text = $(th).text();
if (text.trim() !== "") {
headers[i] = text.replace(/[\t\n\r\s]/mgi, '');
}
});
$('#sport tr').each(function(i, tr) {
// skip if header
if (!$(tr).is('th')) {
var temp = {};
temp["Event"] = $(tr).find('td').eq(0).text().trim();
temp["TopSelection"] = $(tr).find('td').eq(1).text().trim();
temp["BookieOdds"] = $(tr).find('td').eq(2).text().trim();
temp["OLBGRating"] = $(tr).find('td').eq(3).find('img').length;
if (temp["Event"] !== "" || temp["TopSelection"] !== ""){
json.push(temp);
}
}
});
}
// To write to the system we will use the built in 'fs' library.
// In this example we will pass 3 parameters to the writeFile function
// Parameter 1 : output.json - this is what the created filename will be called
// Parameter 2 : JSON.stringify(json, null, 4) - the data to write, here we do an extra step by calling JSON.stringify to make our JSON easier to read
// Parameter 3 : callback function - a callback function to let us know the status of our function
fs.writeFile('output.json', JSON.stringify(json), function(err){
console.log('File successfully written!');
})
// Finally, we'll just send out a message to the browser reminding you that this app does not have a UI.
res.send(json);
});
});
app.listen("8081");
console.log("Magic happens on port 8081");
exports = module.exports = app;
The reason that you're not getting the expected result is because the (table) html on that page is mangled. If you look at the second <td> in the second <tr> of the table#sport, you'll see an "extra" </td>. This causes the <td> that the table#sport is inside to close (and an implicit closing of table#sport) on some parsers because that is the closest open <td>. So that is why the parser reports only 2 <tr>s instead of 13. The other <tr>s you're expecting are now outside of table#sport.
Probably your best bet is to pass the html through an HTML tidying program/script (e.g. this one with the clean option enabled) first before passing it to cheerio. After that, your selector should return the elements you're probably expecting.
I'm trying to create a Node.js application on Heroku that will output 10 different ASCII faces (I already have the module needed for that). Using the Node tutorial on Heroku, I've set it up to output 10 faces. However, when I try to actually run the code, it puts all of the faces inline with each other. How should I try to make it so that the faces are outputted (if that's even a word) on their own lines?
My current index.js is as follows:
var express = require('express');
var app = express();
var cool = require('cool-ascii-faces');
app.set('port', (process.env.PORT || 5000));
app.get('/', function(request, response) {
var result = ''
var times = process.env.TIMES || 5
for (i=0; i < times; i++)
result += cool();
response.send(result);
});
app.listen(app.get('port'), function() {
console.log("Node app is running on port: " + app.get('port'))
})
I have a .env file already set up for Foreman to use (when testing locally) that contains the following:
TIMES=9
If you want to have a look at the output, head on over here.
TL;DR: How do I use newlines in Node?
I visited the site in question and did a View -> Source. There's no markup of any kind like HTML, BODY, etc. I assume that the browser then would interpret the output as HTML. This ought to work since we're using an HTML tag and a pair of PRE tags to indicate that if we see a hard return ('\n') then the browser should display it.
app.get('/', function(request, response) {
var result = '<html><pre>';
var times = process.env.TIMES || 5
for (i=0; i < times; i++)
result += cool() + '\n';
result += '</pre></html>';
response.send(result);
});
By default, the browser assumes that web servers send HTML.
HTML ignores newlines.
If you aren't sending HTML, you need to specify that by setting a different type:
response.header("Content-Type", "text/plain");
To actually send a newline, just concatenate '\n' to your string.
I Have a HTML response. I need to parse it and generate a DOM object. After generation of DOM object I need to search a particular string inside it and get complete hierarchy of HTML tags in which it resides. Is there any NPM package available.
There's an even simpler API for this now in htmlparser2:
var htmlparser = require("htmlparser2");
var dom = htmlparser.parseDOM("<html>your html string</html>");
console.log(dom);
You have htmlparser2 package that can parse HTML stream. You can get the DOM with DomHandler which is bundled with htmlparser2 itself. See the example given there. E.g.
var htmlparser = require("htmlparser2");
var rawHtml = "<html>your html string</html>";
var handler = new htmlparser.DomHandler(function (error, dom) {
console.log(dom);
});
var parser = new htmlparser.Parser(handler);
parser.write(rawHtml);
parser.done();
Parsing DOM object manually is tedious job.
I think that everyone needs a Soup Select(soupselect package) to parse complex DOM objects.
A soupselect is great package in handling DOM.
See following example:
var htmlparser = require("htmlparser2");
var select = require('soupselect').select;
var handler = new htmlparser.DomHandler(function (error, dom) {
if (error)
console.log('error:', error);
else {
// selector reference:
// http://www.w3schools.com/jquery/jquery_ref_selectors.asp
var sel = select(dom, 'body p');
console.log("text in the first <p>: '" + sel[0].children[0].data + "'");
}
});
var parser = new htmlparser.Parser(handler);
var rawHtml =
"<html>"
+ "<head><title>My Title</title></head>"
+ "<body>"
+ "<p>"
+ " Hello World"
+ "</p></body></html>";
parser.parseComplete(rawHtml);
output:
text in the first <p>: ' Hello World'
parseDOM function is now deprecated in htmlparser2 package. You can use parseDocument function now.
const { parseDocument } = require("htmlparser2");
let dom = parseDocument(row_html);
console.log('DOM: ', dom);
I'm using node.js, and I'm trying to add two integers, however, they just put them together...
I've looked up Float, trying to float the integers, but node.js doesn't recognize float.
Apparently at least one of both is actually a string containing a number. V8 then does string concatenation instead of adding the numbers.
What you need to do is to convert the strings to real numbers. You can do that using the parseInt() or parseFloat() functions, but a faster way is to subtract 0: As subtracting from a string is not possible, V8 tries to treat the content of the string as a number.
In the end you also get a number, but AFAIK this method is faster than using the parse functions.
Example:
var foo = '23';
typeof (foo - 0); // => 'number'
var a = '23',
b = '42';
console.log((a - 0) + (b - 0)); // 65
The best way is to cast it before doing any operation for example:
var result = Number(x1) + Number(x2) - Number(x3)
Source: http://www.w3schools.com/jsref/jsref_number.asp
In my node.js I did this.
this is the html file: index.html
<form action="/submission" method="POST">
First Number: <input name = "firstNumber" type="number" /> <br>
Second Number: <input name = "lastNumber" type="number" /> <br>
<input type="submit"/>
</form>
And this is the node.js file: node.js
Now, when you're doing this, you want to call it first too, so you can launch it on your local host, whatever that may be. You can make that choice.
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:false}));
Now I installed body parser up there from my terminal ^ which will be used on my app.post statement down below.
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html'); //Gets the html
});
app.post('/submission', function(req, res) {
var first = parseInt(req.body.firstNumber);
var second = parseInt(req.body.lastNumber);
var sum = Number(first + second);
res.send('The sum is: ' + Number(sum));
});
Then don't forget to run your file on the terminal for your local host. Happy Coding!
I have also same problem but solution is very simple... It's because of String data type
var variable_name="1"; // String Type
console.log(parseInt(variable_name)+1);
**Add this to index.html file**
<form action="http://localhost:3000/sum" method="GET">
<input id = "one" type="number" name="first" value="">
<input id = "two" type="number" name="sec" value="">
<input type="submit" value="OK">
</form>
**Add this to javascript file**
const express = require('express');
const app = express();
app.get('/sum',function(req,res){
var a=Number(req.query.first);
var b=Number(req.query.sec);
var c;
c=a+b;
response = {
result: c
};
console.log(response);
res.end(JSON.stringify(response));
}
);
Then run the file using node.js
With a little delay, but for adding you can subtract the minus value, so
var result = a+b; //Strings appending
becomes
var result = a--b; //Integer a-(-b) --> a+b
I'm just getting into this whole node.js business and like it so far; however I've run into an issue involving connect/mustach.
Here's the code for a simple one page app; at this point I'm really just trying to get the app to use my mustache templates so that I can take it from there.
var connect = require("connect"),
fs = require("fs"),
mustache = require("mustache");
connect(
connect.static(__dirname + '/public'),
connect.bodyParser(),
function(req, res){
var data = {
variable: 'Some text that I'd like to see printed out. Should in the long run come from DB.'
},
htmlFile = fs.createReadStream(
__dirname + "/views/index.html",
{ encoding: "utf8" }
),
template = "",
html;
htmlFile.on("data", function(data){
template += data;
});
htmlFile.on("end", function(){
html = mustache.to_html(template, data);
})
res.end(html);
}
).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
My problem here is that the above code generates a blank webpage.
If I log the html-variable I get two outputs of the html with the variable text attached in it, so the to_html-function seems to do it's job. And if I do res.end('some string'); the string is displayed in the browser as it should.
The template is a plain old .html-file with a <p>{{variable}}</p>-tag in its body.
Any idea what's wrong?
Your problem is that you're not using async code correctly. By the time res.end(html) gets called the file is not yet read. Correct usage:
htmlFile.on("end", function(){
html = mustache.to_html(template, data);
res.end(html);
})
Also you should take care of the syntax error: variable: 'Some text that I'd like to see printed out. Should in the long run come from DB.'
(misuse of ')