trying to parse JSON data results in undefined error - javascript

I'm trying to load a local .json file in my NodeJS application and loop through the items, loading them in a ordered list. I've created my main js file and the model for the data, plus the main html page but I get a strange error. I receive document not defined in my data.js file:
document.getElementById('update').appendChild(makeUl(dataObject));
Here is my main js file, app.js:
var express = require('express' );
var app = express();
var bodyParser = require('body-parser');
app.use(express.static(__dirname+ '/client'));
app.use(bodyParser.json());
var Data = require('./models/data.js');
app.get('/', function(req,res){
res.send("Please use /api/data");
});
app.get('/api/data',function(req, res){
Data.getData(function(err, data){
if (err){
throw err;
}
res.json(data);
});
});
app.listen(5000);
console.log('Connected');
and here is my data.js file where I receive the error:
var dataObject = require("../jsondata/reduced_dataset.json");
function makeUL(array) {
// Create the list element:
var list = document.createElement('ul');
for(var i = 0; i < array.length; i++) {
// Create the list item:
var item = document.createElement('li');
// Set its contents:
item.appendChild(document.createTextNode(array[i]));
// Add it to the list:
list.appendChild(item);
}
// Finally, return the constructed list:
return list;
}
document.getElementById('update').appendChild(makeUL(dataObject));
I don't understand why I receive this error since I've linked it in the html page:
<html>
<head>
<title>Data Parsing</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<div id = "update"> </div>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="app.js"></script>
<script src ="./models/data.js"></script>
</body>
</html>

Related

How do I fix: GET http://... 404 (Not Found)

I have made a JS game. However, nothing shows up on the screen on localhost. When I check the console, I get the following error:
GET http://127.0.0.1:5500/socket.io/?EIO=3&transport=polling&t=NMFSX-v 404 (Not Found)
What does this error mean? How do I fix it?
code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../css/game.css">
<title>Document</title>
<canvas id="ctx" width="500" height="500" style="border: 1px solid #000000;"></canvas>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
<script>
var ctx = document.getElementById("ctx").
getContext("2d");
ctx.fint = '30px Arial'
var socket = io();
socket.on('newPosition', function(data) {
ctx.clearRect(0, 0, 500, 500);
ctx.fillText('P', data.x, data.y);
});
</script>
</head>
<body>
<!-- <div class="circle"></div> -->
<script src="../js/game.js"></script>
<script src="../js/server.js"></script>
</body>
</html>
var express = require('express');
var app = express();
var serv = require('http').Server(app);
app.get('/', function(_req, res){
res.sendFile(__dirname + '../clients/index.html');
});
app.use('../clients', express.static(__dirname + '../clients'));
serv.listen(2000);
console.log("Server started.");
var SOCKET_LIST = {};
var io = require('socket.io') (serv,{});
io.sockets.on('connection', function(socket){
socket.id = Math.random()
socket.x = 0;
socket.y = 0;
SOCKET_LIST[socket.id] = socket;
});
setInterval(function(){
for(var i in SOCKET_LIST){
var socket = SOCKET_LIST[i];
socket.x++
socket.y++
socket.emit('newPosition', {
x:socket.x,
y:socket.y
})
};
},1000/25);
Please can you make sure to post potential solutions in the Answers section?
Thank you SO much for your help!!!
**Edit: Here is a screenshot of the error:
I think the error starts under the line
var io = require('socket.io') (serv,{});
try this block for the lines under instead
io.sockets.on('connection', function(socket){
var socketID=Math.floor(Math.random())*80
while(SOCKET_LIST[socketID]!=undefined){
socketID=Math.floor(Math.random())*80
}
//all that drama above is to(at least meant to) prevent socket overlap(just in case that solves a problem)
socket.id = socketID
socket.x = 0;
socket.y = 0;
SOCKET_LIST[socket.id] = socket;
});
setInterval(function(){
Object.keys(SOCKET_LIST).forEach((a,i)=>{
var socket = SOCKET_LIST[i];
socket.x++
socket.y++
socket.emit('newPosition', {
x:socket.x,
y:socket.y
})
})
},1000/25);
if this doesn't work then the problem is what the frontend tries to access(reason for that 100% strange link it tried to access)
404 (Not Found)
It is the http-error-code for not finding an url.
Edit:
In your given script you call the js-file from the Content Delivery Network of socket.io: "https://cdn.socket.io/socket.io-1.4.5.js".
Check your local script if you mayby made a mistake with transforming it to "http://127.0.0.1:5500/socket.io/?EIO=3&transport=polling&t=NMFSX-v"

Data passed into underscore template is undefined

As mentioned in title, when data is referenced inside of the html template it is undefined.
JS:
var data = [];
for (var i = 0; i < rows.length; i++) {
data.push(rows[i]);
if (i == rows.length - 1) {
fs.readFile('tree.html', 'utf8', function (err, html) {
console.log(data);
var template = _.template(html);
var result = template({ data: data });
res.send(result);
});
}
}
HTML:
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title></title>
</head>
<body>
<%
console.log(data);
%>
</body>
</html>
I'm new to underscore, but it works fine for me. Check what you've missed.
File Structure:
--test.html
--test.js
test.html
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title></title>
</head>
<body>
<%
console.log(data, 'it works! ');
%>
</body>
</html>
test.js
var data = [], rows = [1,2,3,4];
var _ = require('underscore'),
fs = require('fs');
for (var i = 0; i < rows.length; i++) {
data.push(rows[i]);
if (i == rows.length - 1) {
fs.readFile('test.html', 'utf8', function(err, html) {
console.log(html); // correct html file content
var template = _.template(html);
var result = template({
data: data // After console print the html file,
// it runs the script code in html file,
// which in my point of view, means `template` works.
});
// res.send(result);
});
}
}
Run node test.js in the terminal, it works fine.
PS: I did console.log(result) and got the correct result:
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title></title>
</head>
<body>
</body>
</html>

Parsing RSS feed with node.js

I'm trying to get rss to work with node, but it does nothing for me.
Sorry for such a noob question, I've been struggling with this for a while.
Here's my server.js
var express = require('express'),
app = express(),
server = require('http').createServer(app),
RSS = require('rss')
server.listen(3000);
app.set('views', __dirname, 'views');
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
/* lets create an rss feed */
var feed = new RSS({
title: 'Feed',
feed_url: 'https://www.rt.com/rss/',
site_url: 'https://www.rt.com/',
language: 'en'
});
/* loop over data and add to feed */
feed.item({
title: 'item title',
// description: 'use this for the content. It can include html.',
// url: 'https://www.rt.com/rss/', // link to the item
// guid: '1123', // optional - defaults to url
});
// cache the xml to send to clients
var xml = feed.xml();
And here's my index.html
<html>
<head>
<title>Feed</title>
</head>
<body>
<h1>Feed</h1>
<div id="content"></div>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
var content = <%= feed.item %>;
var <%= feed.item %> = "true";
</script>
</body>
</html>
When I run node server.js, there's only the h1 title in the index page.

How to make an aggregate template file for UnderscoreJS template

Intro
I'm trying to create an aggregate file with all of my UnderscoreJS templates in it. I'll explain how I've achieved this with a JSP app with a Java backend.
How I got it working in my JSP app:
When using jsp pages, you're able to do:
<html>
<head> ... </head>
<body>
...
<jsp:include page="./path/to/aggregate_templates.jsp"/>
</body>
</html>
And in this file, you can have all of your UnderscoreJS templates listed like so:
<jsp:include page="./path/to/js/view/home/file.template"/>
<jsp:include page="./path/to/js/view/home/file2.template"/>
...
Question
Rather than a Java backend, I'm using a NodeJS server. Is there a way I can have an aggregate template file on the fly that does the same thing as jsp:include? Or is my only option something like this: Templating using RequireJS (text.js plugin) and Underscore?
The solution:
Append all *.template files together with fileUtil.aggregateTemplates() into aggregate.template
When index.html is loaded in the browser, main.js runs
Before doing anything else, main.js calls TemplateCache.setup()
TemplateCache.setup() adds the contents of aggregate.template to $("#templates")
All templates are now in the html and at the Backbone views' disposal
The code:
In app.js
...
var fileUtil = require('./utils/file-util');
var aggregateTemplateFile = 'path/to/aggregate.template';
var targetDir = 'path/to/directory/containing/template/files';
fileUtil.aggregateTemplates(targetDir, aggregateTemplateFile);
...
In file-util.js
var fs = require('fs');
var path = require('path');
/**
* Traverse the directory
* #param dir - directory to traverse
* #param cond - callback for determining whether or not to keep file
* #param done - callback for what to do with results
*/
var walk = function(dir, cond, done){
var results = [];
fs.readdir(dir, function(err, list){
if(err){
return done(err);
}
var i = 0;
(function next(){
var file = list[i++];
if(!file){
return done(null, results);
}
file = path.resolve(dir, file);
fs.stat(file, function(err, stat){
if(stat && stat.isDirectory()){
walk(file, cond, function(err, res){
results = results.concat(res);
next();
});
}else{
if(cond(file)){
results.push(file);
}
next();
}
});
})();
});
};
/**
* Create aggregate file
* #param fileArr - array of files (full path)
* #param targetFile - file to print to (full path)
* #param strictOrder - (optional) boolean whether or not to enforce order
*/
var createAggregate = function(fileArr, targetFile, strictOrder){
if(!fileArr || fileArr.length<1){
return;
}
fs.writeFileSync(targetFile, ""); // clear file
if(strictOrder){
var i = 0;
(function next(){
var file = fileArr[i++];
if(!file){
return;
}
fs.readFile(file, function(err, data){
if(err) throw err;
fs.appendFileSync(targetFile, data);
next();
});
})();
return;
}
for(var i=0; i<fileArr.length; i++){
var file = fileArr[i];
fs.readFile(file, function(err, data){
if(err) throw err;
fs.appendFileSync(targetFile, data);
});
}
};
/**
* Create an aggregate template file
* #param targetDir - directory to look in (full path)
* #param targetFile - file to print to (full path)
*/
exports.aggregateTemplates = function(targetDir, targetFile){
// Determine what kind of files we care about
var isTemplate = function(file){
return file.match(/.+\.template$/);
};
// Determine what we do with the results
var done = function(err, result){
if(err) throw err;
createAggregate(result, targetFile);
};
// Traverse the target directory
walk(targetDir, isTemplate, done);
};
In index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>MyApp</title>
<link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="/lib/bootstrap/css/bootstrap-custom.css">
<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.css">
<link rel="stylesheet" href="/stylesheets/style.css">
<link rel="stylesheet" href="/stylesheets/style-responsive.css">
</head>
<body class="center-on-page">
<div id="header" class="affix"></div>
<div id="content"></div>
<div id="javascript">
<!-- JavaScript Library Imports -->
<!-- JavaScript Local Imports -->
<!-- Code Entry Point -->
<script type="text/javascript" src="/js/main.js"></script>
</div>
<!-- Underscore Templates -->
<div id="templates"></div>
</body>
</html>
In main.js
(function(){
$.when(app.util.TemplateCache.setup())
.done(function(){
// Start the router
new app.Router();
Backbone.history.start();
});
})();
app.util.TemplateCache.setup
app.util.TemplateCache.setup = function(){
var opts = { url: "aggregate.template" };
return $.ajax(opts)
.done(function(data, textStatus, jqxhr){
console.log("Loaded aggregate template file");
$("#templates").html(data);
})
.fail(function(data, textStatus, jqxhr){
console.log("Failed to load aggregate template file");
});
};

Node.js Express | Always getting null when trying to get a JSON

I am very new to node.js and I want to receive on an HTML5 website JSON from a PostgreSQL database. So, on the server side I use node-postgres module for DB connection and also express module for communication. The PostgreSQL query is returning a JSON object.
Server-side:
var express = require('express');
var app = express();
app.get('/data', function(req, res){
var pg = require('pg');
var conString = "postgres://postgres:postgres2#localhost/spots";
var client = new pg.Client(conString);
client.connect(function(err) {
if(err) {
res.send('could not connect to postgres');
}
client.query('SELECT * from spots_json where id=3276', function(err, result) {
if(err) {
res.send('error running query');
}
res.send(JSON.stringify(result.rows[0].json));
client.end();
});
});
});
app.listen(3000);
Client-side:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js" ></script>
<script>
$.get('http://localhost:3000/data',{}, function(data){
alert(JSON.parse(data));
},"json");
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
If I navigate to http://localhost:3000/data on the browser I get:
{\"type\":\"Point\",\"coordinates\":[-2.994783,43.389217]}
So I see that the server is sending the stringified JSON properly, but on the client I always get null data. I must have some misconception.
Ok this is how my code is so far, for anyone that could help:
serverside
var express = require('express');
var app = express();
app.get('/data', function(req, res){
var pg = require('pg');
var conString = "postgres://postgres:postgres2#localhost/spots";
var client = new pg.Client(conString);
client.connect(function(err) {
if(err) {
res.send('could not connect to postgres');
}
client.query('SELECT * from spots_json where id=3276', function(err, result) {
if(err) {
res.send('error running query');
}
res.set("Content-Type", 'text/javascript'); // i added this to avoid the "Resource interpreted as Script but transferred with MIME type text/html" message
res.send(JSON.stringify(result.rows[0].json));
client.end();
});
});
});
app.listen(3000);
clientside
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"></meta>
<meta charset="utf-8"></meta>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.js" ></script>
<script>
$.get('http://localhost:3000/data?callback=?',{}, function(data){
alert(data.type);
},"json");
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
The client is now executed on http://localhost:8888/prueba/prueba.html
Im getting a js with the following Response:
"{\"type\":\"Point\",\"coordinates\":[-2.994783,43.389217]}"
The Response can be seen in the following screenshot:
https://www.dropbox.com/s/zi4c5pqnbctf548/pantallazo.png
But now the alert isn't even shown...
I think i need some light with this.
The data is already an object when you get it, not a string. So JSON.parse fails because you gave it an object when it was expecting a string. To verify, change
alert(JSON.parse(data));
to
alert(data.type);
and you should get "Point"
The reason you already have an object is because of the "json" parameter you provided to $.get. If you change that to "html" you will get a string back instead which you could then parse out into a JSON object.
I think you should not try to stringify your result when you put it in the response object.
Just put it entirely it will automaticaly that way :
res.set("Content-Type", 'application/json');
res.json(result.rows[0].json);
That is the right way to send information through REST APIs.
Then in your client side code, I don't know how it works but it should accept json natively.

Categories

Resources