using data from JSON in NodeJS - json

Hello i just started learning Nodejs and made a local server as a start
then i saw that most nodejs apps have config and package files i couldnt find any info on how to do a simple one or use JSON files so i tried myself this is what i got so far
this is the server file
var http = require('http');
var json = require('./package');
var fs = require('fs');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(addr.port);
console.log('server listening at', addr.address + ':' + addr.port);
and this is the json file
{
"addr": {
"address":"http://127.0.0.1",
"port":"8081"
}
}
i know that it will work with json.address and json.port
but when i added "addr" i thought it would simplify things with addr.port
so in short an explanation would be generously accepted on why it wont/shouldnt work or what im doing wrong

First of you should have a look at some tutorials or introduction sites like:
https://www.w3schools.com/nodejs/default.asp
Second:
The package.json file is the main configuration file of your nodeJS application. Thats the config file that defines your start point of your application as well as all included modules. simply use npm init to create a default package.json file with basic information.
Third:
If you require a json into your application as you did in your example the JSON is included hierarchically. Wich means The object you required has an attribute addr which itself is a new object with an attribute address.
So the correct way to access your information is json.addr.address based on your object description
you could also do something like this:
var network = require('./settings').addr;
console.log("ip => " + network.address);
console.log("port => " + network.port);

You need to list the parent object. You have put addr.address and addr.port, this means you are directly trying to access the addr object, but the this object doesn't exist. Try doing json.addr.address and json.addr.port and it should work.
var http = require('http');
var json = require('./package');
var fs = require('fs');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(json.addr.port);
console.log('server listening at', json.addr.address + ':' + json.addr.port);

Related

Casperjs requiring local JSON file

I am trying to require local JSON files (such as config files) and pass those JSON objects to evaluate. For each config file, evaluate function will return different results depending on the given CSS selectors from config JSON.
For example:
The folder structure is like this:
rootdir
casperExample.js
config/
|_example.json
example.json
{
"title": "$('div.pointslocal-details-section h1').text();",
"date": "$('div.pointslocal-details-time p').text();"
}
casperExample.js
var casper = require('casper').create();
var require = patchRequire(require);
var json = require('./config/example.json');
casper.start('https://website/to/be/scraped');
casper.then(function(){
this.echo(json);
pageData = this.evaluate(function(json){
var results = {};
results['title'] = json.title;
results['date'] = json.date;
return results;
}, json);
this.echo(pageData);
});
casper.run(function(){
this.exit();
});
This is what I get when I try to run: casperjs casperExample.js
CasperError: Can't find module ./config/example.json
C:/Users/msarc/coding/casper/rootdir/phantomjs:/code/bootstrap.js:307 in patchedRequire
and if I use var json = require('./config/example'); (without .json) I get
SyntaxError: Expected token '}'
C:/Users/msarc/coding/casper/rootdir/phantomjs:/platform/example.js:32 in loadModule
C:/Users/msarc/coding/casper/rootdir/phantomjs:/platform/bootstrap.js:282 in _compile
C:/Users/msarc/coding/casper/rootdir/phantomjs:/platform/bootstrap.js:126 in .js
C:/Users/msarc/coding/casper/rootdir/phantomjs:/platform/bootstrap.js:278 in _load
C:/Users/msarc/coding/casper/rootdir/phantomjs:/platform/bootstrap.js:311 in require
C:/Users/msarc/coding/casper/rootdir/phantomjs:/platform/bootstrap.js:263 in require
C:/Users/msarc/coding/casper/rootdir/phantomjs:/code/bootstrap.js:302 in patchedRequire
I want to eventually make multiple config files, each with different selectors for different websites. casperjs version: 1.1.4 phantomjs version: 2.1.1
You're requireing json file as if it were a javascript module, which it is of course not, hence the error. Instead you need to read the file and process it is JSON structure:
var fs = require('fs');
var fileContents = fs.read('config/_example.json');
var json = JSON.parse(fileContents);
Then proceed working as planned.

Accessing req.body values in express

I'm working on a REST API node/express app. For my 'signup' route, where a user uses the api to sign up for the service, it takes a POST'ed JSON object. Inside this function I want to check against the mongo db to make sure that this user doesn't already exist.
The problem is I need to get the username from the posted json information, but every attempt I have made has failed. The lines that attempt to log the req.body.username and req.body.password always return 'undefined'. What am I doing wrong?
Here's the code I have so far is below:
exports.signup = function(req, res) {
// todo: somehow verify that username, password, email and phone number are all provided.
// do not write into the collection unless we know all the information has been provided.
// maybe access the JSON elements to make sure they are not null
// todo: also make sure a record doesn't already exist for this uer
var user = req.body;
// need to get the username here somehow
var JSONuser = JSON.stringify(user);
// console.log('user: ' + user);
console.log('userJSON: ' + JSON.stringify(user));
console.log('username: ' + req.body.username);
console.log('password: ' + req.body.password);
db.collection('users', function(err, collection){
//if ( collection.findOne({}) ) { // make sure the user doesn't already exist here
collection.insert(user, {safe:true}, function(err, result){
if(err){
res.send({'error':'An error has occured'});
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
})
//}
});
}
By default in express, you don't have access to those variables through dot syntax. You would have to parse the response. Luckily, we have a package for that.
Use body-parser middle ware for easy access to post variables.
// install it
bash$: npm install body-parser
// require it in your project
bodyParser = require('body-parser');
// `use` it in your express app
app.use(bodyParser.urlencoded({ extended: true}));
// now you your post values are available on the req.body.postVariableName
I use this in almost all of my projects, it just makes it easy.
* EDIT *
I looked at your repo and everything actually looks fine as it pertains the reading of parsed values; however, they way you are console logging them may be where you are getting confused. I rewrote your signin route so I could explain better.
exports.signin = function(req, res) {
var user = req.body;
console.log('req.body: ' + JSON.stringify(user));
console.log('Signing In As User: ' + user.username);
console.log('Password: ' + user.password);
res.send('You just signed in!');
}
I tested this my opening up another terminal and curling a JSON post.
curl -H "Content-Type: application/json" -X POST -d '{"username":"testuser","password":"testpassword"}' http://localhost:3000/signin
As you can see it should work.
Some things worth mentioning. When you wrote console.log('req.body: ' + req.body);. You are not going to see the data you want. You are going to see req.body: [object] in the output because javascript is going to render this as req.body.toString() which is just the identifier. If you want to post the code, use JSON.stringify(req.body) or use console.dir(req.body).
Second, req.body will just give u access the body object.
// this is just user.toString() which is again [object]
console.log('Signing In As User: ' + user);
// You need to use the dot syntax to get user.username
console.log('Signing In As: " + user.username);
If you are stilling seeing issues, its because of the way you are making posts localhost, not because of your code.

avoid caching in rest api using node.js

I searched a lot about the subject and why/how to avoid restfull api caching, butI didn't get a helpful answer.
I built expressjs api to generate random json data using faker module everything went fine for the first request but any refresh on the browser or any additional requests display the same data.
I want with every request generate a random data but I think after the first request the nodejs module is cached.
I'm using
nodejs: the latest version,
expressjs: v4.0,
faker: the latest
my code as below:
in the router file: router.js
var router = express.Router();
router.get('/name', controller.name);
.
.
in the controller file: json.controller.js
//Get name
var name = require('name.model.js');
exports.name = function(req, res){
var randomName = name;
return res.json(200, randomName);
};
in the model file: name.model.js
var faker = require('faker');
var nameModel = {};
nameModel.name = faker.name.findName();
module.exports = nameModel;
Can any one help how to avoid rest api caching? and how to fix it in my case?
Thanx for any help,
The problem was that I didn't understand moduke.exports and exports in node.js
After reading Understanding module.exports and exports in Node.js
I changed the module to be:
var exports = module.exports = {};
exports.getName = function(){
return faker.name.findName();
}
Voila! that fixed the issue I was facing, and I started getting new data everytime I post a request to the server.
I hope this will help any one needs to understand module.exports and exports

node.js readfile error with utf8 encoded file on windows

I'm trying to load a UTF8 json file from disk using node.js (0.10.29) on Windows 8.1. The following is the code that runs:
var http = require('http');
var utils = require('util');
var path = require('path');
var fs = require('fs');
var myconfig;
fs.readFile('./myconfig.json', 'utf8', function (err, data) {
if (err) {
console.log("ERROR: Configuration load - " + err);
throw err;
} else {
try {
myconfig = JSON.parse(data);
console.log("Configuration loaded successfully");
}
catch (ex) {
console.log("ERROR: Configuration parse - " + err);
}
}
});
I get the following error when I run this:
SyntaxError: Unexpected token ´╗┐
at Object.parse (native)
...
Now, when I change the file encoding (using Notepad++) to ANSI, it works without a problem.
Any ideas why this is the case? Whilst development is being done on Windows the final solution will be deployed to a variety of non-Windows servers, I'm worried that I'll run into issues on the server end if I deploy an ANSI file to Linux, for example.
According to my searches here and via Google the code should work on Windows as I am specifically telling it to expect a UTF-8 file.
Sample config I am reading:
{
"ListenIP4": "10.10.1.1",
"ListenPort": 8080
}
Per "fs.readFileSync(filename, 'utf8') doesn't strip BOM markers #1918", fs.readFile is working as designed: BOM is not stripped from the header of the UTF-8 file, if it exists. It at the discretion of the developer to handle this.
Possible workarounds:
data = data.replace(/^\uFEFF/, ''); per https://github.com/joyent/node/issues/1918#issuecomment-2480359
Transform the incoming stream to remove the BOM header with the NPM module bomstrip per https://github.com/joyent/node/issues/1918#issuecomment-38491548
What you are getting is the byte order mark header (BOM) of the UTF-8 file. When JSON.parse sees this, it gives an syntax error (read: "unexpected character" error). You must strip the byte order mark from the file before passing it to JSON.parse:
fs.readFile('./myconfig.json', 'utf8', function (err, data) {
myconfig = JSON.parse(data.toString('utf8').replace(/^\uFEFF/, ''));
});
// note: data is an instance of Buffer
To get this to work without I had to change the encoding from "UTF-8" to "UTF-8 without BOM" using Notepad++ (I assume any decent text editor - not Notepad - has the ability to choose this encoding type).
This solution meant that the deployment guys could deploy to Unix without a hassle, and I could develop without errors during the reading of the file.
In terms of reading the file, the other response I sometimes got in my travels was a question mark appended before the start of the file contents, when trying various encoding options. Naturally with a question mark or ANSI characters appended the JSON.parse fails.
Hope this helps someone!
New answer
As i had the same problem with several different formats I went ahead and made a npm that try to read textfiles and parse it as text, no matter the original format. (as original question was to read a .json it would fit perfect). (files without BOM and unknown BOM is handled as ASCII/latin1)
https://www.npmjs.com/package/textfilereader
So change the code to
var http = require('http');
var utils = require('util');
var path = require('path');
var fs = require('textfilereader');
var myconfig;
fs.readFile('./myconfig.json', 'utf8', function (err, data) {
if (err) {
console.log("ERROR: Configuration load - " + err);
throw err;
} else {
try {
myconfig = JSON.parse(data);
console.log("Configuration loaded successfully");
}
catch (ex) {
console.log("ERROR: Configuration parse - " + err);
}
}
});
Old answer
Run into this problem today and created function to take care of it.
Should have a very small footprint, assume it's better than the accepted replace solution.
function removeBom(input) {
// All alternatives found on https://en.wikipedia.org/wiki/Byte_order_mark
const fc = input[0].charCodeAt(0).toString(16);
switch (fc) {
case 'efbbbf': // UTF-8
case 'feff': // UTF-16 (BE) + UTF-32 (BE)
case 'fffe': // UTF-16 (LE)
case 'fffe0000': // UTF-32 (LE)
case '2B2F76': // UTF-7
case 'f7644c': // UTF-1
case 'dd736673': // UTF-EBCDIC
case 'efeff': // SCSU
case 'fbee28': // BOCU-1
case '84319533': // GB-18030
return input.slice(1);
break;
default:
return input;
}
}
const fileBuffer = removeBom(fs.readFileSync(filePath, "utf8"));

Creating a non-REST JSON API server with node

I am relatively new to NodeJS, but I'm porting an existing API server written in PHP to use NodeJS. I started out looking at Express, but realised that with all the layout-rendering and templating stuff in Express, it wasn't suited for the task. Then I looked at Restify, but realised it's REST-ness wouldn't work with the model of this API.
I don't want anything that is tied to a database, or any specific way of setting out the API endpoints. Is the best solution to fully roll my own server, without the help of any libraries?
EDIT: Sorry, it seems I was unclear. I am trying to recreate the PHP API as close as possible, and the PHP version does not use REST. It has a few different PHP scripts which take some POST parameters.
If you just want a simple JSON API, Express is still an option. Layouts, temptating and middleware are optional, and you can just use simpler functions.
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.post('/', function(req, res) {
// req.body is an object with POST parameters
// respond with JSON
res.json(200, { data: 'payload' })
// or show an error
res.json(500, { error: 'message' });
});
app.listen(80);
That is one of the simplest solutions available. Unless you want to do request body parsing, checking the HTTP request method, other things yourself, then you can create your own server. That would look more like this:
var http = require('http');
http.createServer(function(request, response) {
if (request.method === 'POST') {
var data = '';
request.on('data', function(chunk) {
data += chunk;
});
request.on('end', function() {
// parse the data
});
}
}).listen(80);
A method like so would also require checking the path as well as other things that would be handled automatically in Express.