I've recently started using MEAN Stack to create a basic application, so im a total beginner, I set up my controllers and everything and I want to post, however it returns api/user not found, can someone pinpoint the problem and help me out? Thanks.
Server.js:
var app = require ('./app/app');
var signupController = require ('./server/signup-controller');
app.post('api/users', signupController.create);
app.listen('8080', function(){
console.log('[OK] => HTTP Server listening on http://localhost:8080');
require('./app/db').init('mongodb://localhost:27017/shopialmedia' );
});
Server side Controller (signup-controller.js):
module.exports.create = function (req, res) {
console.log(req.body);
}
Client Side Controller (signup-controller.js):
app.controller('signupController', ['$scope', '$resource', function ($scope, $resource) {
var User = $resource('/api/users');
$scope.createUser = function () {
var user = new User();
user.email = $scope.userEmail;
user.password = $scope.userPass;
user.firstName = $scope.userFName;
user.lastName = $scope.userLName;
user.age = $scope.userAge;
user.$save(function (result){
$scope.user.push(result);
$scope.userEmail = '';
$scope.userPass = '';
$scope.userFName = '';
$scope.userLName = '';
$scope.userAge = '';
});
}
}]);
My module :
var app = angular.module('signupApp', ['ngResource']);
My app.js :
var express = require ('express');
var app = express();
app.use(express.static('public'));
require('./routes')(app);
module.exports = app;
When I go to run the application on my web page and submit the information, it returns api/user 404 Not found any suggestions on what to do, I'd greatly appreciate it. As I said im a beginner so please take that into consideration.
Server.js Add:
app.get('api/users', signupController.list);
signup-controller.js Add:
mongoose = require('mongoose'),
User = mongoose.model('User');
module.exports.list = function(req, res){
var searcher = req.query || {};
User.find(searcher)
.sort('-created')
.exec(function (err, users) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
}
res.json(users);
});
};
Obviously, you'll also have to connect to mongoose with a file probably called main.js then you'll need a UserModel.js (or equivalent) where you can define the attributes of your user etc using the mongoose Schema...
I mean you're missing a lot if you want something a little simpler to start you can just do:
module.exports.list = function(req, res){
var users = [];
res.json(users);
};
Also think you need this and this is also nicer formatting:
var router = express.Router();
router.route('/')
.get(users.list)
.get(users.create)
app.use('/api/users', router);
Not sure what this is supposed to do or what ./routes is: require('./routes')(app);
Related
i have a problem and i don't know the problem. Please, help me to find the solution.
In the Angular view i have:
<form ng-submit="submit()">
<input ng-model="stickie_text" type="text" id="sticky_content" />
<button type="submit" id="add_sticky" value="add a new stickie!">new sticky</button>
In the client side (AngularJS) i have this controller:
dcuApp.controller('rankingController', ['$scope', '$http',function($scope, $http) {$scope.submit = function(){
// console.log("holaaaa");
console.log($scope.stickie_text);
$http.get('/api/get-ranking',{"valor":$scope.stickie_text}).then(function(response) {
$scope.data = response.data;
console.log("RANKING: "+$scope.data);
},
function(response) {
console.debug('Error:' + response);
});
};
}]);
In the server side (Express 4.13.1) i have:
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var db = require('../model/db');
var model = require('../model/model');
var fs = require('fs');
var async = require('async');
var bodyParser = require('body-parser');
var methodOverride = require('method-override'); //used to manipulate POST
router.use(bodyParser.urlencoded({ extended: true }))
router.use(methodOverride(function(req, res){
if (req.body && typeof req.body === 'object' && '_method' in req.body) {
// look in urlencoded POST bodies and delete it
var method = req.body._method
delete req.body._method
return method
}
}));
router.get('/api/get-ranking',function(req,res,next){
console.log(req.body.valor);
});
The problem is that req.body.valor is UNDEFINED.
I know there are other postings that relate to this problem, but have not managed to fix it.
Please, I need help to get on the server side, a different req.body.valor to undefined
thanks!!! :)
You are trying to do a GET request and send data along with it. You need to use POST request to achieve what you want. You cannot send data in a GET request.
You need to change your current GET method to POST.
Replace :
router.get('/api/get-ranking',function(req,res,next){
console.log(req.body.valor);
});
with
router.post('/api/get-ranking',function(req,res,next){
console.log(req.body.valor);
});
also,
Replace :
$http.get('/api/get-ranking',{"valor":$scope.stickie_text})
with:
$http.post('/api/get-ranking',{"valor":$scope.stickie_text})
Hope this helps.
I am sending filename to server and trying to get some sort of response to make sure api calls are working but its always returing 404 even though path is correct, I am not sure where i am making mistake , Any idea ?
angularjsFactory.js
getFile:function(file_name){
return $http.get("/file?file_name="+file_name);
}
server.js
var express = require('express');
var app = express();
var fs = require('fs');
app.use(express.static(__dirname + "/public"));
var readDirectory = require('./readDirectory');
app.get('/file', function(req, res) {
var path = './ditLogs';
var fileParam = req.query.file_name;
console.log(fileParam);
fs.readdir(path, function(err, items) {
items.forEach(function(items) {
if (fileParam === items) {
res.sendFile(items);
console.log(items);
}
});
});
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
//console.log('app is printing data',obj);
//ditProducer.startProducer();
setTimeout(function() {
ditconsumer.start();
}, 2000);
});
Your route on server is not correct comparing to the call from angular's side. You are not using route parameters, but query string.
Try this:
app.get('/file', function (req, res) {
// get filename using: req.query.file_name
res.send('FIle data');
});
Or you can try this on angular and keep the server code:
$http.get("/file/"+ encodeURI(file_name));
Server side code looks incorrect.
app.get('/file', function (req, res) {
console.log(req.query.file_name);//This will give you filename passed as url param
res.send('FIle data');
});
I'm making an ionic app for android and today I implemented a server side nodejs (express) Restful API with mongodb on cloud9.
But when I trigger a http request to the url, I keep getting the error mentioned in the title:
This is my angular http request on ionic (simply to test first):
app.controller('DashCtrl', function($scope, $http, $q) {
$http.get('https://[workspace]-[user].c9users.io/api/capture')
.then(function(result) {
console.log(result);
});
});
This is an image of my workspace:
I used the following code to make the database:
api.js
var Capture = require('../models/capture');
module.exports = function(router) {
router.get('/capture', function(req, res){
var capture = new Capture();
// capture.birdname = req.body.birdname;
// capture.place.city = req.place.body.city;
// capture.place.country = req.place.body.country;
capture.birdname = "Pigeon";
capture.save(function(err, data){
if(err)
throw err;
res.json(data);
});
});
router.get('/captures', function(req, res){
Customer.find({}, function(err, data){
res.json(data);
})
})
}
capture.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var captureSchema = mongoose.Schema({
birdname: String,
place: {
city: String,
country: String
}
});
module.exports = mongoose.model('Capture', captureSchema)
database.js
module.exports = {
'url': 'mongodb://' + process.env.IP
}
server.js
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var configDB = require('./server/config/database.js');
mongoose.connect(configDB.url);
var api = express.Router();
require('./server/routes/api')(api);
app.use('/api', api);
app.listen(process.env.PORT, process.env.IP);
console.log('Listening on port ' + process.env.PORT)
Anyone have an idea why I'm getting this error and what I need to do to fix this?
I'm guessing it has something to do with the server allowing me to send requests to the API though I don't know how to implement that.
Is there also a way to secure my database (API key maybe) and how would I implement this?
Thanks in advance
I'm new to nodejs and dived into using mongoose for mongodb. Let me show you the code structure that I made knowing that I'm doing a mistake somewhere. Suppose from angular using $http.post I'm sending an object to be inserted into db. The way I'm trying to insert the data into the database doesn't seem to work.
Mongoose Schema Contacts.js
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/contactlist');
var ContactSchema = new mongoose.Schema({
name: String,
email : String,
number : String
}, {collection:'contactlist'});
var ContactModel = mongoose.model('ContactList', ContactSchema);
module.exports = ContactModel;
Node server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
var db = require('./model/Contacts.js');
var contact = new db();
require('./routes/routes.js')(app, db, contact);
Node routes.js
module.exports = function(app, db, contact){
// post api
app.post('/contacts', function(req,res){
var body = req.body;
contact.save(body, function(err, data){
res.json(data);
});
});
};
I'm messing up somewhere with inserting the data into database specially with the new db() and passing it to the routes file. I'm not sure what I'm missing here. And how can I improve these scripts after the insertion is solved?
Try this
Mongoose Schema Contacts.js
var mongoose = require('mongoose');
var ContactSchema = new mongoose.Schema({
name: String,
email : String,
number : String
}, {collection:'contactlist'});
var ContactModel = mongoose.model('ContactList', ContactSchema);
module.exports = ContactModel;
Node server.js
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
app.use(bodyParser.json());
var contacts = require('./model/Contacts.js');
require('./routes/routes.js')(app);
mongoose.connect('mongodb://localhost/contactlist');
Node routes.js
var contacts = require('./model/Contacts.js');
module.exports = function(app){
// post api
app.post('/contacts', function(req,res){
var body = req.body;
// not sure about contact vs contacts here
contact.save(body, function(err, data){
res.json(data);
});
});
};
As part of server.js you are creating document, i.e instance of mongoose model and after that you are passing that document to exported function of routes.js module. From there you are "victim" of javascript closures. Inside of '/contacts' route handler contact will always be the same thing (document that you passed from server.js).
Then in your route handler you are using mongoose .save() method in a wrong way, providing data which you want to save as a first parameter. Please read: http://mongoosejs.com/docs/api.html#model_Model-save,
Now lets try to force your example to work and see what will happen, surely thing that you didn't want to happen.
module.exports = function(app, db, contact) {
app.post('/contacts', function(req,res){
contact.name = req.body.name;
contact.email = req.body.email;
contact.number = req.body.number;
contact.save(function(err, data){
res.json(data);
});
});
};
With this you will end with updating always the same document, the document with same id in mongoose collection due to reasons explained at the beginning of the answer.
So what you want to do is to create new document whenever there is a POST to '/contacts'.
var Contact = require('path to Contact model');
module.exports = function(app) {
app.post('/constacts', function (req, res) {
var contact = new Contact(req.body);
contact.save(function(err) {
if(err) {...}
...
});
});
};
By the way, move mongoose.connection logic out of your models, that needs to be part of bootstraping application logic and db is probably terrible name to be used for the purposes for which you are using it.
How to parse form elements array in NodeJS ?
Like in PHP we get $_POST['answers'] for form elements with names: answers[0], answers[1], answer[2] .... answers[n]
I got my own solution for this, for example I am getting data in var obj:
console.log("\n\n\n\n\n\n\n\n\n");
var obj = {
'answer[\'test\']': 'first',
'answer[\'2\']': 'second'
};
var new_obj = {};
for(key in obj){
key.replace(/([^\[]+)\['([^\]]+)'\]/g, function($0, $1, $2){
new_obj[$1] = new_obj[$1] || {};
new_obj[$1][$2] = obj[key];
})
}
console.log(new_obj);
Check out formidable it can parse any form you give it. It's also the module that connect and express use to parse the form data.
Using the popular node.js framework Express, it is as simple as:
var express = require('express'),
app = express.createServer();
app.use(express.bodyParser());
app.post('/foo', function(req, res, next) {
// Echo the POST body
res.send(req.body);
});
app.listen(3000);
Testing with curl:
curl -d foo=1 -d foo=2 localhost:3000/foo
Similar to in PHP, req.body.foo will be an array with all the foos you posted.
Edit: The querystring module is indeed what Express uses internally. If you need to accept file uploads, use formidable as Jan Jongboom suggests. Otherwise, here's basically how you would do it with just node:
var http = require('http'),
qs = require('querystring');
var app = http.createServer(function(req, res) {
var buffer = '';
req.setEncoding('utf-8');
req.on('data', function(data) {
buffer += data;
});
req.on('end', function() {
var body = qs.parse(buffer);
});
});