MongoDB does not refresh data automatically? - angularjs

I use MEAN stack for developing. And after adding some data to MongoDB, the new data is available in front-end only after restarting NodeJS server. There is any way to update MongoDB data 'online'?
This is my API (Node.js):
var express = require('express');
var mongoose = require('mongoose');
var router = express.Router();
mongoose.connect('mongodb://localhost/vt');
var Video = mongoose.Schema({
idv: String,
thumbnail: Number,
aud : String,
title : String,
description : String
});
var db;
var video = mongoose.model('video',Video);
video.find({}, function (err, data) {
db = data;
});
router.get('/api/videos', function (req, res) {
res.send(db);
});
module.exports = router;
I am adding data via Mongo Shell, it looks like this: db.videos.insert({'idv': '8ifJvMlITNc'}). After that, I get all data from videos table via Ajax. There is no new data in the response from the server until I restart Node.js server

In your Node.js app you are fetching the data only once. You are not fetching it when request is received. Change the code to following and you don't have to restart for reading data:
var express = require('express');
var mongoose = require('mongoose');
var router = express.Router();
mongoose.connect('mongodb://localhost/vt');
var Video = mongoose.Schema({
idv: String,
thumbnail: Number,
aud : String,
title : String,
description : String
});
var video = mongoose.model('video',Video);
router.get('/api/videos', function (req, res) {
video.findOne({}, function (err, data) {
if (err || !data) {
res.status(500).send();
}
res.status(200).send(data);
});
});
module.exports = router;
Hope this helps.

Related

How to post JSON object angularjs

I would like post object and read it on node server but I have an error.
controller :
$scope.update = function(contact) {
console.log(contact);
$http.post('/contactlist/' + contact).then(function(response) {
console.log(response);
});
};
server node :
app.post('/contactlist/:contact', function (req, res, next) {
console.log(req.body);
res.json();
});
server node head:
var express = require('express');
var app = express();
var mysql = require('mysql');
var bodyParser = require('body-parser');
var connection = *****************
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({extended:false}));
app.use(express.static(__dirname + "/public"));
Screenshot of the error network POST :
enter image description here
server error of console.log(req.body);
[object Object]
SyntaxError: Unexpected token o in JSON at position 1
You are not passing any parameter in your post API. POST needs a parameter to be passed and since you are passing the parameter in the request URL, you can try by passing an empty object like this:
$http.post('/contactlist/' + contact,{}).then(function(response) {
console.log(response);
});
You are trying to concatenate an object in the URL which is not a good approach. If you want to still do this way, stringify it and then append it to URL. And you can get it with the help of req.query. But it is better if you change the url and pass contact as a parameter to your API call.
Problem solved by :
var OBJ = JSON.stringify(yourOBJ);
For node js there different syntax please see below:
var yourObj = {};
$http.post('/contactlist/' + contact, {data: yourObj}).then(function(response)
{
console.log(response);
});
This will work

XMLHttpRequest cannot load [url] Response for preflight is invalid (redirect)

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

Data insertion to mongodb with mongoose and angular

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.

"SyntaxError: Unexpected token n" in Express Node Server

I get this error-
SyntaxError: Unexpected token n
at parse (/Users/afroza/node_modules/body-parser/lib/types/json.js:83:15)
at /Users/afroza/node_modules/body-parser/lib/read.js:116:18
at invokeCallback (/Users/afroza/node_modules/raw-body/index.js:262:16)
at done (/Users/afroza/node_modules/raw-body/index.js:251:7)
at IncomingMessage.onEnd (/Users/afroza/node_modules/raw-body/index.js:308:7)
at IncomingMessage.emit (events.js:104:17)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)
I creating a route with nodejs and I'm getting this error,I've tried many things and there's no way, always appears this error,
my server setup in express framework-
var express = require('express');
var app = express()
, fs = require('fs')
, path = require('path');
var env = process.env.NODE_ENV || 'production'
, config = require('./config/config')[env]
, mongoose = require('mongoose');
var http = require('http');
var db = mongoose.connect('mongodb://localhost/orbitax');
app.use(express.static(__dirname + '/public'));
var bodyParser = require('body-parser'); // add body-parser for interact with server and client data
var jsonParser = bodyParser.json(); //join this body parser with json file
var urlencodedParser = bodyParser.urlencoded({ extended: false});
//Initialize Models
var models_path = __dirname + '/app/models'
fs.readdirSync(models_path).forEach(function (file) {
require(models_path+'/'+file)
});
require('./config/routes')(app,config);
var server = app.listen(9000, function(){
var host = server.address().address;
var port = server.address().port;
});
server routing,
var async = require('async')
, mongoose = require('mongoose')
, uploadModel = mongoose.model('uploadModel');
module.exports = function (app) {
// upload routes
var upload = require('../app/controller/upload');
app.get('/newUpload', upload.newUpload);
app.post('/create_new_directory', upload.create_new_directory);
}
exports.create_new_directory = function(req, res)
{
console.log("hello")
console.log(req.body);
}
and from client side request is,
$http({'method': 'post', 'url': '/create_new_directory', data: $scope.directory })
.success(function(data){
console.log(data)
})
.error(function(){
})
Any help would be appreciated, Thanks.
By default, the $http service will only transform request data to a JSON string if the data is an object.
https://github.com/angular/angular.js/blob/v1.4.8/src/ng/http.js#L292
In your case, the request data is a string so it is not getting wrapped in quotes, making it invalid JSON.
You should be able to modify your $http config like this:
$http({
method: 'POST',
url: '/create_new_directory',
data: $scope.directory,
transformRequest: JSON.stringify
}).success(function(data){
console.log(data)
})

node.js form elements array

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);
});
});

Resources