I am building a simple MySQL, Express, Angular, Node app and using Sequelize as my ORM. When I create a new survey, the values I am sending do not get set, as the req.body is an empty object.
server.js
'use strict';
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var bodyParser = require('body-parser');
var models = require('./server/models/');
var routes = require('./server/routes');
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(express.static(process.cwd() + '/public'));
//App routes
app.use(routes(express.Router()));
app.get('/*', function (req, res) {
res.sendFile('index.html', {
root: './public'
});
});
app.listen(port, function() {
console.log('Server running on port %s ', port);
});
app.js
'use strict';
// Declare app level module which depends on views, and components
var app = angular.module('myApp', []);
app.controller('SurveyController', ['$scope', '$http', function($scope, $http) {
//Get all Surveys
$http.get("/surveys")
.then(function(response) {
$scope.surveys = response.data;
});
$scope.create = function() {
$http.post("/surveys",{
question: $scope.question,
answers: $scope.answers,
user: $scope.user
})
.then(function(response) {
});
}
}]);
model
'use strict';
module.exports = function(sequelize, DataTypes) {
var Survey = sequelize.define('Survey', {
question: DataTypes.STRING,
answers: DataTypes.STRING,
user: DataTypes.STRING
}, {
underscored: true,
classMethods: {
associate: function(models) {
// associations can be defined here
}
}
});
return Survey;
};
routes.js
var surveys = require('./controllers/surveys');
module.exports = function (router) {
//routes
router.get('/surveys', surveys.get);
router.get('/surveys/:id', surveys.getOne);
router.post('/surveys', surveys.create);
router.put('/surveys', surveys.update);
router.delete('/surveys', surveys.delete);
return router
};
controller
//Create a new survey
create: function(req, res) {
//this req.body and req.params are both empty
Survey.create(req.body)
.then( function(newSurvey) {
res.status(200).json(newSurvey);
})
.catch( function(error) {
res.status(500).json(error);
})
},
I recently had a similar problem here: Why is my req.body always empty on POST? but the solution for that did not work for this issue. I am presuming it is similar but the solution has alluded me so far.
Don't need to stringify
$http
.post("/surveys", {
question: $scope.question,
answers: $scope.answers,
user: $scope.user
},
{
headers: { 'Content-Type': 'application/json; charset=UTF-8'}
})
Per many comments above (many thanks to all), I solved this by changing my bodyParser implementation from
app.use(bodyParser.urlencoded({
extended: true
}));
to
app.use( bodyParser.json() );
Related
I am trying to do my first API Rest and I am following some tutorials. I am requesting all the articles in a MongoDB database.
This is the code of the main:
var express = require("express"),
app = express(),
http = require("http"),
bodyParser = require("body-parser"),
methodOverride = require("method-override"),
server = http.createServer(app),
mongoose = require('mongoose');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(methodOverride());
// Import Models and controllers
var models = require('./models/article')(app, mongoose);
var articleCtrl = require('./controllers/articleController');
// Example Route
var router = express.Router();
router.get('/', function(req, res) {
res.send("Hello world!");
});
articles.route('/articles/:id')
.get(articleCtrl.findById);
articles.route('/articles')
.get(articleCtrl.findAllarticles)
.post(articleCtrl.addarticle);
app.use('/api', articles);
app.use(router);
mongoose.connect('mongodb://localhost/ustcg', { useNewUrlParser: true ,useUnifiedTopology: true}, function(err, res) {
if(err) {
console.log('ERROR: connecting to Database. ' + err);
}
app.listen(3000, function() {
console.log("Node server running on http://localhost:3000");
});
});
The code of the controller is here:
// Import article and mongoose
var mongoose = require('mongoose');
var Article = mongoose.model('Article');
//GET - Return a article with specified ID
exports.findById = function(req, res) {
Article.findById(req.params.id, function(err, Article) {
if(err) return res.send(500, err.message);
console.log('GET /article/' + req.params.id);
res.status(200).jsonp(Article);
});
};
//GET - Return all articles in the DB
exports.findAllarticles = function(req, res) {
Article.find(function(err, Article) {
if(err) res.send(500, err.message);
console.log('GET /article')
res.status(200).jsonp(Article);
});
};
//POST - Insert a new article in the DB
exports.addarticle = function(req, res) {
console.log('POST');
console.log(req.body);
var Article = new Article({
title: req.body.title,
paragraphs: req.body.paragraphs
});
Article.save(function(err, Article) {
if(err) return res.send(500, err.message);
res.status(200).jsonp(Article);
});
};
The model:
//We create the model
exports = module.exports = function(app, mongoose) {
var ArticleSchema = new mongoose.Schema({
title: { type: String },
paragraphs: { type: Array },
});
mongoose.model('Article', ArticleSchema);
};
When I tried to request the following http request it send me 404 error. I can not see any logs on the console so it is not entering the methods in order to see the exception is happening so I am stucked with this...
If someone could help me it would be nice.
what is articles variable in your main file.
I tried your code in my machine and struggled with articles variable and you have extra imports which are not required.
Try following code it works fine
var express = require("express");
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
var articleCtrl = require('./sample.controller');
var router = express.Router();
router.get('/', function(req, res) {
res.send("Hello world!");
});
router.get('/articles/:id', articleCtrl.findById);
router.post('/articles', articleCtrl.addarticle);
router.get('/articles', articleCtrl.findAllarticles)
// app.use('/api', router);
app.use(router);
app.listen(3000, function() {
console.log("Node server running on http://localhost:3000");
});
if you uncomment app.use('/api', router); then you can also use routes as localhost:3000/api/articles
I am creating a MEAN stack application using AngularJS and Node.js.
Here is my AngularJS code:
app.js:
var app = angular.module('crudApp', ['ngRoute']);
app.config(['$routeProvider','$locationProvider',
function($routeProvider,$locationProvider){
$routeProvider
.when('/employees/create', {
templateUrl : 'create.html',
controller : 'EmployeeController'
}).when('/nothing', {
templateUrl : 'main.html',
controller : 'mainController'
});
$locationProvider.html5Mode(true);
}]);
app.controller('EmployeeController',function($scope,$http) {
$scope.save = function(data) {
$scope.data = JSON.stringify(data);
console.log(data);
$http.post("http://localhost:8080/employees/create-employee",$scope.data).then(function(response) {
console.log("posted successfully");
});
};
});
Here is my Node.js code:
server.js:
var express = require('express');
var app = express();
var cors = require('cors');
var bodyParser = require('body-parser');
app.use(cors());
app.use(express.static(__dirname + '/angularjs/public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use('*',function(req, res) {
res.sendFile(__dirname + '/angularjs/public/index.html');
});
require('./node/routes')(app);
app.listen(8080);
routes.js:
module.exports = function(app) {
app.get('/employees/create-employee',function(req,res) {
console.log(req.body);
});
Angular part is working fine, displays data in console, posting the data and getting "posted successfully" message.
But in node, I am unable to get the posted data in req.body.
I am getting the "create.html" content when I checked in browser "network".
Need someone's help.
Use this
module.exports = function(app) {
app.post('/employees/create-employee',function(req,res) {
console.log(req.body);
});
And for get you should use req.params
module.exports = function(app) {
app.get('/employees/create-employee',function(req,res) {
console.log(req.params);
});
I'm trying to define a model in account.js and export it to my server.js file. When I try to create a new instance of the model, I get this error:
"TypeError: Account is not a constructor
It's probably simple mistake but I couldn't figure out why it's not recognizing it as a constructor.
These are my files:
account.js
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const accountSchema = new Schema({
fullname:{
type: String,
required: true,
},
username:{
type: String,
required: true,
unique: true,
}
}, {
collection: 'accounts',
});
mongoose.connect('mongodb://localhost/accountsdb', (error) => {
if(error) console.log(error);
console.log("Database connection successful.");
});
module.exports = mongoose.model('Account', accountSchema);
Server.js
var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
const Account = require("account");
var app = express();
app.use(express.static('assets'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.get('/', function(req, res) {
res.sendFile('index.html', {root : __dirname + '/'});
});
app.post('/signup', function(req,res){
console.log(req.body);
const newAccount = new Account(req.body); //ERROR here
newAccount.save((err) => {
if(err) throw err;
res.redirect('/');
});
});
app.use(express.static(__dirname + '/'));
app.listen(3000);
console.log('Listening on port 3000');
In your server.js, your import for Account is wrong. Import like this instead:
const Account = require("./account");
The problem here is with the way you required Account. Without a "/", "./" or "../" prefixed to account in require('account'), it is trying to import a core module or one of the node_modules (if in main directory).
I am learning node and express to create an api for an angular app I will be creating.
When I try and post something the req.body seems to be blank.
This is my server.js file
'use strict';
var express = require('express'),
app = express(),
mongoose = require('mongoose'),
router = require('./api'),
bodyParser = require('body-parser');
mongoose.connect('mongodb://localhost/my_db');
app.use(bodyParser.json());
app.use('/api', router);
app.get('/', function(req, res) {
res.render(__dirname + '/index.jade');
});
app.listen(3001, function() {
console.log('Listening on port 3001');
});
and this is my api/index.js file:
'use strict';
var express = require('express'),
Todo = require('../models/todo'),
router = express.Router();
router.get('/todos', function(req, res) {
Todo.find({}, function(err, todos) {
if(err) {
return console.log(err);
}
res.json({todos: todos});
});
});
router.post('/todos', function(req, res) {
var todo = req.body;
res.json({todo: todo});
});
module.exports = router;
when I use postman to post this to http://localhost:3001/api/todos:
{
'name': 'Walk the Dog',
'completed': false
}
my response is:
{
"todo": {}
}
I can't see why this would be blank, any help is appreciated.
UPDATE
Turns out I was posting text in postman instead of JSON.
use this in your server.js file
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
I am pretty new with node.js and express so bear with me please.
I am wondering how i can get a mysql instance and use it in my controller. I have 4 files that look like this:
see my comment in the controller.js file
server.js :
var express = require('./config/express');
var app = express();
module.exports = app;
app.listen(3000);
console.log('server running');
express.js :
var express = require('express'),
bodyParser = require('body-parser'),
mysql = require('mysql');
module.exports = function() {
var app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.set('views','./app/views');
app.set('view engine','ejs');
//NOT SURE WHAT TO DO HERE OR WHERE TO PUT THE CONNECTION DETAILS
var dbConnection = mysql.createConnection({
host : 'localhost',
user : 'someuser',
database : 'somedb',
password : 'somepass'
});
//connection.connect();
//
//connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) {
// if (err) throw err;
// console.log('The solution is: ', rows[0].solution);
//});
//
//connection.end();
require('../app/routes/index.server.routes.js')(app);
app.use(express.static('./public'));
return app;
};
routes.js :
module.exports = function(app) {
var index = require('../controllers/index.server.controller');
app.get('/', index.render);
app.post('/', index.stuff);
};
controller.js :
exports.render = function(req, res) {
//DO DB STUFF HERE
res.render('index', {
title: 'this is the title'
});
};
exports.stuff = function(req, res) {
res.render('index', {
title: 'this is the title post'
});
};
To use the connection instance in your controller, you'll need to pass it from the express.js file to the controller.js file. The first step is to pass the connection instance to the router:
express.js
require('../app/routes/index.server.routes.js')(app, connection);
This will make it available in the routes.js file. You then need to pass the same connection instance to the controller.
index.server.routes.js
module.exports = function(app, connection) {
var index = require('../controllers/index.server.controller')(connection);
app.get('/', index.render);
app.post('/', index.stuff);
};
The controller will need to be refactored so it takes a connection instance as an argument:
index.server.controller.js
function IndexController(connection) {
controllerMethods = {};
controllerMethods.render = function (req, res) {
// You can use the connection instance here.
connection.connect()
// Run your query
connection.end()
...
};
// Define other methods for the controller
// Return the object that holds the methods.
return controllerMethods;
}
module.exports = IndexController;