ExpressJS POST cannot log body - json

After a lot of fiddling with upgrading versions and the different middleware/ways of using a body parser, I am still stuck.
I have an Iphone app which POSTs 2 things (2 separate things). First is an image, which works.
Second is a json object which i try to put into mongodb.
No matter what i do, i can't seem to log the contents of the request.
var express = require('express');
var logger = require('morgan');
var fs = require('fs');
var json = require('express-json');
var path = require('path');
var errorHandler = require('errorhandler');
MongoClient = require('mongodb').MongoClient,
Server = require('mongodb').Server,
CollectionDriver = require('./collectionDriver').CollectionDriver;
FileDriver = require('./fileDriver').FileDriver;
...
app.use(json());
//app.use(bodyParser.urlencoded({ extended: true }));
app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
...
app.post('/:collection', function(req, res) {
console.warn(req.body.poi.toString());
var object = req.body;
var collection = req.params.collection;
console.warn("Post: " + req.toString());
collectionDriver.save(collection, object, function(err,docs) {
if (err) { res.send(400, err); }
else { res.send(201, docs); }
});
});
I've tried logging (log, warn) req.body, req, etc. to no avail.
i'm using express-json and NOT url encoding, don't think need it.
morgan ouputs the following when i post
POST /pois 200 15.983 ms - 63
and nothing else!

It apparently cannot do it, as stated in this closed issue https://github.com/expressjs/morgan/issues/16
morgan is not intended for this kind of work. Try and use Winston instead, or simply console.log

This does it for me:
const express = require('express')
const app = express()
app.use(express.json())
var morgan = require('morgan')
morgan.token('response-body', (req, res) => {return JSON.stringify(req.body)}); // define 'response-body' token using JSON.stringify
app.use(morgan(':method :url :response-time :response-body')) //include newly defined ':response-body' token
app.post(/....)

Related

Can feathers co exist with routs managed out side of feathers

We have a large app which uses express for rest and primus for socket routes. It would be very hard to convert all to feathers at once. I am thinking of phased approach where I could take some routes and convert them to services and of cause any new routes will follow the service pattern. I will slowly migrate the rest of the app.
The client is using primus and angularjs $http for now to communicate with nodejs.
our current set up looks like
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
const csrf = require('csurf');
var Primus = require('primus');
var SocketService = require('./../services/socket-service'); ////this handles existing socket routes from primus client using spark.write
var routesUtils = require('../utilities/routes-utility');
var _ = require('lodash');
module.exports = function(isClusteredDeploy) {
var app = express();
var server = http.createServer(app);
var primus = new Primus(server, {transformer: 'uws'});
var socketService = SocketService(primus);
var commonSocketRoute, commonRoute;
//primus.library();
//primus.save(__dirname + '/primus-client.js');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json({
strict: false,
limit: '1mb'
}));
app.use(cookieParser());
app.use(csrf({ cookie: true }));
app.use(function (err, req, res, next) {
if (err.code !== 'EBADCSRFTOKEN') {
return next(err);
}
res.status(403);
res.send();
});
app.use(function(req, res, next) {
res.cookie('XSRF-TOKEN', req.csrfToken());
next();
});
server.listen(config.get(constants.CONFIG_App_Port), function() {
log.info('App server ==> %s is listening on port %d', config.get('rest_host_config.' + config.get('app_key') + '.host'),
config.get(constants.CONFIG_App_Port));
});
//dynamically loading rest routes and socket routes from the file system
var files = routesUtils.readRoutes(true);
files.forEach(function(file) {
if (_.includes(file, 'socket')) {
commonSocketRoute = require('./../../' + file);
commonSocketRoute(socketService);
} else {
commonRoute = require('./../../' + file);
commonRoute(app);
}
});
};
I'd like to add feathers in this and then slowly start converting. Is this possible?
Yes, with the standard #feathersjs/express framework integration your Feathers application will also be a fully Express compatible application which additionally allows to register services.
In your case you would replace var app = express(); with:
const feathers = require('#feathersjs/feathers');
const express = require('#feathersjs/express');
// Create an app that is a Feathers AND Express application
const app = express(feathers());
// Set up REST services (optional)
app.configure(express.rest());
And everything should continue to work as normal. The next step would be to replace the custom Primus code with the #feathersjs/primus framework adapter:
const feathers = require('#feathersjs/feathers');
const express = require('#feathersjs/express');
const primus = require('#feathersjs/primus');
// Create an app that is a Feathers AND Express application
const app = express(feathers());
// Set up Primus with SockJS
app.configure(primus({ transformer: 'ws' }));
Now you can also replace the http.createServer setup with a more simple
const server = app.listen(config.get(constants.CONFIG_App_Port))
Since Feathers will handle all the Express and Primus initialization. The Primus instance will be available as app.primus.

valid json format gives error “<“ while parsing also view engine error 500 using mean stack angular 2+

Mean server with angular 2+.
I have a dataservice.js that requests a get to the server, to receive a json response from the http://localhost:3000/server/routes/api/test.js
This gives me an error 500 view engine not selected,
My understanding is angular doesn’t require a view engine? As the angular/ browser takes care of that.
Somehow the routing doesn’t seem to work when I do a getter to the api.
The angular routes work with the html components, but via the dataservice a get request to the mongodb doesn’t work either. The get/test most often returns error 500 no view engine selected as well.
If it does return something, it returns an error message “<“ not in jsn format.
How do I make sure that the routing works for my get and post messages and they are returned back in json format and not in HTML.
And how do I figure out that it uses the correct routing? I somehow doubt that the rouitng for the get/ post messages seem to use express rather then the angular modules
I am quite new to stack overflow/ Mean server so if you require more info please let me know.
FYI
I have been able to get a json file from the server (not the database) via a get. This worked. So why is it that a get to the database doesn’t seem to work and the same question about why I can’t seem to get a json response from the http://localhost:3000/server/routes/test/api.js in the api.
I spent a full 2 days troubleshooting to no result.
in my api.js
router.get ('/test', function (req, res, next) {
res.json({'testMessage': 'everything is going ', 'someNumber': 457});
});
In the server.js
<!-- end snippet -->
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var morgan = require ('morgan');
var mongoose = require('mongoose');
var flash = require('connect-flash');
var chat = require('./server/routes/chat');
var app = express();
var passport = require ('passport');
var cookieParser = require ('cookie-parser');
var session = require ('express-session');
var config = require ('./config/database');
var engines = require('consolidate');
var mongoose = require('mongoose');
var router = express.Router();
// this is where I set up the routing for the api
// in the root of the project I created server directory and
// within it a routes directory that holds the api.js
var api = require('./server/routes/api');
mongoose.Promise = require ('q').Promise;
require('./config/passport')(passport);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended':'true'}));
app.use(express.static(path.join(__dirname, 'dist')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(morgan('dev'));
app.use(session({
secret: 'secret123',
resave: true,
saveUnitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
//this is where I set up the routing is something wrong here?
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
app.use('api', api);
thx everyone, I moved
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
below
app.use('api', api);
and changed it to:
app.use('/api', api);
Problem solved, if app.get('*') is read first it will send all requests to index.html instead. So make sure any other routings go above it.

Gets Error when adding MySQL information in server.js when creating RESTful API with Express

I was following instructions to build a RESTful API with Express and MySQL(*1)
But when I change
app.listen(port); //excutable, GET returns welcome message
into
orm.initialize(WConfig.config,function(err,models){
...
in the part 2 of(*1), which is adding MySQL information into server.js,
I gets the following on Node.JS command prompt:
TypeError: Cannot read property 'bear' of undefined
Because this is the first attempt in building RESTful API, I'm not sure what to do to fix it. Help please! Any idea is appreciated.
full code of server.js:
// server.js
var util = require('util');
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var Waterline = require('waterline');
var Bear = require('./app/models/bear');
var WConfig = require('./app/config/waterline');
var orm = new Waterline();
orm.loadCollection(Bear);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080;
var router = express.Router();
router.get('/', function(req, res) {
res.json({ message: 'hello! welcome to our api!' });
});
app.use('/api', router);
// express deprecated res.json(obj,status): use res.status(status).json(obj) instead
router.route('/bears')
.post(function(req,res) {
app.models.bear.create(req.body,function(err,model) {
if(err) return res.status(500).json({ err,err });
res.json(model); //res.json(model) , guess: res.status(200).json(model);
console.log(util.inspect(model));
});
});
//gets error if I change it to following
//
orm.initialize(WConfig.config,function(err,models){
if(err) throw err;
app.models = models.collections;
//app.set('models',models.collections);
app.connections = models.connections;
app.listen(port);
console.log('Magic happens on port ' + port);
});
reference:
1.Create Restful API with Express and waterline (in Chinese)
https://segmentfault.com/a/1190000004996659#articleHeader2
2.Build a RESTful API Using Node and Express 4
https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4

NodeJs cat server empty JSON output issue

I a beginner following a nodejs tutorial.
From said tutorial, I generated the following code:
[Index.js]
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
var cats = require('./cats.js')(app);
var server = app.listen(3000, function(){
console.log('Server running at http://127.0.0.1/3000');
});
[Cat.js]
var _ = require('lodash');
module.exports = function(app){
_cats = [];
/*
Create
*/
app.post('/cat', function(req, res){
console.log('Testing: ' + req.body);
res.json({info: 'Cat created successfully!'});
});
/*
Read
*/
app.get('/cat', function(req, res){
res.send(_cats);
});
.
.
.
.
When I start the node script, and post some json cat data as described in the tutorial, my web browser displays empty json brackets for each json input I made.
Can anyone tell me what I missed or I'm doing wrong? Why do I get empty JSON brackets instead of my cat data printed out?
I'm an utter newbie at NodeJS so I apologise if I have not described issues adequately.
UPDATE:
I'm using the Postman Chrome extension to POST json, {'name':'sam','age':'1','type':'alley'} to http://localhost:3000/cat.
The tutorial I'm following is on PluralSight. I don't think it's accessible without an account but they do offer a couple of days free to get you started.
Take a look at this working sample:
var express = require('express');
var app = express();
var cats = [];
var counter = 1;
app.post('/cat', function (req, res) {
cats.push({id: counter, name: 'Jacklyn'});
counter++;
res.json({info:'cat created successfully'});
});
app.get('/cat', function(req, res) {
res.json(cats);
});
app.listen(8888);
You need to send at least one POST request in order to have a cat in the array and after each new POST request the amount of cats will increase.
It's because the code you posted does not update the _cats array. The code for post handler should be:
app.post('/cat', function(req, res){
console.log('Testing: ' + req.body);
_cats.push(req.body); // This is the missing line
res.json({info: 'Cat created successfully!'});
});
Here I assume that the body contains a single object and it is already parsed. If not, you can add required manipulations...
Edit
It seems that the request body should be parsed. The express framework has an additional module, the body-parser, which is used for this purpose:
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // this will parse json requests
For more information, see bodyParser on GitHub.

export json object from .json file to vue through express and assign it to the variable

I would like to display on my page some data which I have in dsa.json file. I am using express with vue.
Here's my code from the server.js:
var data;
fs.readFile('./dsa.json', 'utf8', (err, data) => {
if (err) throw err;
exports.data = data;
});
Here's code from between <script> tags in index.html
var server = require(['../server']);
var data = server.data;
var scoreboards = new Vue({
el: '#scoreboard',
data: {
students: data
}
});
I am using requirejs (CDN) to require server between <script> tags in index.html.
index.html is in public directory whereas dsa.json and server.js are in the main catalogue.
Here are the errors I get in the client:
require.min.js:1 GET http://localhost:3000/server.js
require.min.js:1 Uncaught Error: Script error for "../server"
I think it has something to do with context and scope but I don't know what exactly.
I am using Chrome.
Your approach is completely wrong. You can't include the server script on your page. Also, I'm not a NodeJS ninja, yet I don't think that exporting the data inside the function will work -> exports.data = data.
The workaround:
Server side:
const fs = require('fs');
const express = require('express');
const app = express();
const data = fs.readFileSync('./dsa.json', 'utf8'); // sync is ok in this case, because it runs once when the server starts, however you should try to use async version in other cases when possible
app.get('/json', function(req, res){
res.send(data);
});
Client side:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/json', true);
xhr.addEventListener('load', function() {
var scoreboards = new Vue({
el: '#scoreboard',
data: {
students: JSON.parse(xhr.response)
}
});
});
xhr.addEventListener('error', function() {
// handle error
});
xhr.send();