Can't get data from MongoDB database for web app - javascript

I'm new to using MongoDB. Currently, I am making a web application that requires some data storage. I established an HTTP server on Node.js that runs on localhost:3000. I also built a virtual development environment using Vagrant and VirtualBox. I am accessing the Mongo shell from PuTTy (if that is relevant at all). Before incorporating MongoDB, it worked fine as I was storing the data in the Node.js program memory.
This web app is an online to-do-list. The first error that I am getting is with the get route. The list of "to-do"s that I have inserted into the Mongo database would not appear on the site in localhost. It seems to not be getting the data from the database. The second error that I am getting is with the post route. When I insert a "to-do" through the user interface at localhost and I refresh the page, the to-do-list on localhost gets updated with that particular to-do (but not with the ones I inserted in the database). But, it doesn't seem to add it into the database, and I still get this error on the console:
vagrant#precise32:~/app$ node server.js
{ description: 'descTest3', tags: [ 'tagTest3' ] }
Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
I'm not sure why I got that error since I do not seem to be using any promises.
server.js
var express = require("express"), http = require("http"), app = express(), mongoose = require("mongoose");
app.use(express.static(__dirname + "/client"));
app.use(express.urlencoded());
mongoose.connect('mongodb://localhost/WatNext');//connect to the WatNext data store in mongoDB
var ToDoSchema = mongoose.Schema({
"description": String,
"tags": [ String ] //array of Strings
});
var ToDo = mongoose.model("ToDo", ToDoSchema)
http.createServer(app).listen(3000);
//get and post routes:
app.get("/toDos.json", function (req, res) {
ToDo.find({}, function (err, toDos) {
if (err != null){
console.log(err);
}
res.json(toDos);
});
});
app.post("/todos", function (req, res) {
console.log(req.body);
var addedToDo = new ToDo({"description" : req.body.description, "tags" : req.body.tags});
//save function saves object into the database
addedToDo.save(function (err, result) {
if (err != null){//if there is an error
console.log(err);
res.send("ERROR SAVING");
}
else {
ToDo.find({}, function (err, result) {
if (err != null){//if there is an error in finding
res.send("ERROR FINDING");
}
res.json(result);
});
}
});
});
app.js
var main = function (toDoObjects) {
//do stuff with ToDoObjects including outputting the list of ToDos
};
$(document).ready(function() {
$.getJSON("toDos.json", function(toDoObjects) {
main(toDoObjects);
})
});
mongo shell
> show dbs
WatNext 0.0625GB
local 0.03125GB
> use WatNext
switched to db WatNext
> show collections;
system.indexes
toDoCollection
todos
> db.toDoCollection.find();
{ "_id" : ObjectId("58b38dd8fb355f57162d9cf1"), "description" : "Get groceries and eat afterwards", "tags" : [ "shopping", "chores" ] }
{ "_id" : ObjectId("58b38dd8fb355f57162d9cf2"), "description" : "Make up some new To-Dos", "tags" : [ "writing", "work" ] }
{ "_id" : ObjectId("58b38dd8fb355f57162d9cf3"), "description" : "Prep for Monday's class", "tags" : [ "work", "teaching" ] }
{ "_id" : ObjectId("58b38dd8fb355f57162d9cf4"), "description" : "Answer emails", "tags" : [ "work" ] }
{ "_id" : ObjectId("58b38dd8fb355f57162d9cf5"), "description" : "Take April to the park", "tags" : [ "chores", "pets" ] }
{ "_id" : ObjectId("58b38dd8fb355f57162d9cf6"), "description" : "Finish writing this book", "tags" : [ "writing", "work" ] }
EDIT:
I found out it was just an error of naming.
I also found out that
mongoose.Promise = require("bluebird");
solved the problem with the promise error. Remember to install the module first though:
npm install --save bluebird

I found out what was wrong. It was an error in naming for the GET and POST routes. It should have been:
app.get("/todos.json", function (req, res) { //get the data from the collection called 'todos' in MongoDB
as well as:
$.getJSON("todos.json", function(toDoObjects) {
I should have used the todos collection instead of toDoCollection:
"description" : "descTest1", "_id" : ObjectId("58b39a1fb1a30305075408fa"), "tags" : [ "tagTest2" ], "__v" : 0 }
{ "description" : "descTest2", "_id" : ObjectId("58b4c837d47a5604c7c0609a"), "tags" : [ "tagsTest2" ], "__v" : 0 }
{ "description" : "descTest3", "_id" : ObjectId("58b4ca0491f4c804d200cda9"), "tags" : [ "tagTest3" ], "__v" : 0 }
{ "description" : "descTest4", "_id" : ObjectId("58b4e636b71d0a05ebb7a71a"), "tags" : [ "tagTest4" ], "__v" : 0 }
{ "description" : "descTest5", "_id" : ObjectId("58b60211428520053a4714ed"), "tags" : [ "tagTest5" ], "__v" : 0 }
{ "_id" : ObjectId("58b6037839e65d96e13cf68e"), "description" : "descTestMONGO", "tags" : [ "tagTestMONGO" ] }
{ "_id" : ObjectId("58b605b339e65d96e13cf690"), "description" : "Take April to the park", "tags" : [ "chores", "pets" ] }

Related

How I can get ID of a new record in mongoDB?

There is such a document structure in MongoDB
{
"_id" : ObjectId("58f7d556aa52ce456672a67e"),
"created" : ISODate("2017-04-19T21:23:34.315Z"),
"context_task" : [
{
"task" : "some text ",
"status" : false,
"_id" : ObjectId("58f7d559aa52ce456672a67f")
}
],
"head" : {
"userID" : "58f48037fc894e19a3f7b81b",
"head_task" : "test record "
},
"__v" : 0
}
I add data to the context_task.task using the following query:
task.findOneAndUpdate({"_id": req.body.id_project},
{$push: {'context_task': {'task': req.body.input_task,'status': false}}},{new: true},
function (err, doc) {
if (err) return next(err);
var body = req.body.id_project+","+req.body.input_task;
console.log(doc);
res.status(200).send(body);
});
Tell me, how can I get the context_task._id of a new record after inserting it? In this case, the entire document is returned.
Every mongo document is associated with a default _id, in case not provided it will be ObjectId.
In case you want to use _id value for any other purpose, why don't you have your own _id value, which has to be unique throughout collection. The value can be of any datatype as well as nested also.

adding an object that represents users to an array after signup using passport

I am trying to make a list of username and passwords so that when a user signs in with their credentials they can see all the data that everyone else sees but they still have to use their own credential. I wanted to make a list of objects like this users : [{username : "user1", password : "pass1"}, {username : "user2", password : "pass2"}]. this should be created on signup. I though subdocs would help but I'm not getting what I want. I have this:
var userlist = new mongoose.Schema({username: String, password : String })
var userSchema = new mongoose.Schema({
users : [userlist]
})
and I attempted to add the new users to the array like this:
app.post("/signup", function(req, res){
var user = new User;
user.users.push({username : req.body.username, password : req.body.password})
user.save(function(err){
if(err) return handleError(err);
console.log("success")
})
// User.create(users : [{username : req.body.username, password : req.body.password}], function(err, doc){
// console.log(doc);
// })
res.redirect("/login")
})
this givs me this
> db.users.find().pretty()
{
"_id" : ObjectId("56ba6219763de71c03199a70"),
"users" : [
{
"username" : "user1",
"password" : "pass1",
"_id" : ObjectId("56ba6219763de71c03199a71")
}
],
"__v" : 0
}
{
"_id" : ObjectId("56ba6225763de71c03199a72"),
"users" : [
{
"username" : "user2",
"password" : "pass2",
"_id" : ObjectId("56ba6225763de71c03199a73")
}
],
"__v" : 0
}
>
It's making separate documents. I want it to look like this
{
"_id" : ObjectId("56ba6219763de71c03199a70"),
"users" : [
{
"username" : "user1",
"password" : "pass1",
"_id" : ObjectId("56ba6219763de71c03199a71")
},
{
"username" : "user2",
"password" : "pass2",
"_id" : ObjectId("56ba6225763de71c03199a73")
}
],
"__v" : 0
}
Having the objectIDs in the subdocs are not so important to me . I just want to group all the users together so that when they go to login I could do something like if the doc is there the credentials are good so continue to other parts of website.
I am not sure if you have resolved you question by now or not, regardless here is the answer to your problem.
Firstly if you don't need _id in subdocument then state that in the schema accordingly and no _id will be created.
var userSchema = new Schema({ username: String, password: String},{ _id: false });
If you use the above schema for user then there should be no _id field in the subdocument.
You should know that to insert a subdocument you need to know the parent for it. If you don't provide the parent while inserting the subdocument then for each insert a new parent is created. In this case parent contains _id and users subdocument. If I have the exact problem, I would go about solving it the following way:
The schema designs remain the same as shown below (I named them differently to avoid confusion):
var userSchema = new Schema({username: String, password: String},{ _id : false });
var userListSchema = new Schema({
users: [userSchema]
});
Now I will declare the parent model as follow:
var UserList = mongoose.model('UserList', userListSchema);
//see below what list gets assigned.
var list;
Now let's assume I have a route handler where I would like to keep adding the users upon sign up something as shown below:
app.get("/newuser/:username/:password", function(req, res) {
//create user model
var User = mongoose.model('User', userSchema);
//load user module, for testing i use params, you can change this to req.body
var user = new User({username: req.params.username, password: req.params.password});
//I would like to find the first document in userlists collection
UserList.findOne({}, function(err, result) {
if(err) console.log(err);
//below if condition is true, if there is one document with users subdoc
if(result) {
console.log('Found existing document with users subdocument. Adding user to array.')
//assign the parent where the subdoc should be inserted to list
list = result;
//there already is a document with subdocument users, so append to it
list.users.push(user);
//save the changed list.
list.save(function(err) {
if (err) console.log(err);
console.log('User saved.');
});
} else {
console.log('No document found. Creating one and adding this user to users subdocument.');
// initialize list model with first ever user
list = new UserList({ users: [user] });
//save the new changed list
list.save(function(err) {
if (err) console.log(err);
console.log('User saved.');
});
}
})
});
Done. Now when I run the app and access the following URL for the first time
http://127.0.0.1:8080/newuser/user1/pass1
The userslist collection would look as follow:
> db.userlists.find().pretty();
{
"_id" : ObjectId("56c349d6479f5b9b1eaea1c8"),
"users" : [
{
"password" : "pass1",
"username" : "user1"
}
],
"__v" : 0
}
I would like to access the link with different params as shown below:
http://127.0.0.1:8080/newuser/user2/pass2
And the output of the collection looks as follow:
{
"_id" : ObjectId("56c349d6479f5b9b1eaea1c8"),
"users" : [
{
"password" : "pass1",
"username" : "user1"
},
{
"password" : "pass2",
"username" : "user2"
}
],
"__v" : 1
}
Now I terminate the app and then re-run the app and access the following url:
http://127.0.0.1:8080/newuser/user7/pass7
And the output of the collection looks as follow:
{
"_id" : ObjectId("56c349d6479f5b9b1eaea1c8"),
"users" : [
{
"password" : "pass1",
"username" : "user1"
},
{
"password" : "pass2",
"username" : "user2"
},
{
"password" : "pass7",
"username" : "user7"
}
],
"__v" : 2
}
There you go. I feel bad to see that userlists collection would always always always have one document and its array would keep expanding, maybe not a good practice to solve your issue in this manner. If I were you, I would store each user as a single record and then do the group by or any other aggregation operation.

Unable to retireve objects from Mongoose-Node

I have a Mongodb database with resume objects like below. I am using a node-express server. And I am querying the mongo database to get objects based on a specific skill. For example: If I query for a skill: jquery, only objects with that skill is returned. The problem is with the get function that is returning objects from the database.
In the highlighted code: If I directly insert the object like:
Resume.find({skills.jQuery : 2},function(err, results){...}
then I get the expected results.
However if I insert it dynamically (skillSet), then it doesnot work. Iit checked the value for skillSet and it give me what I expect('skills.JQuery')
var skillSet = ("'"+'skills.' + req.params.skill +"'");
console.log('skillSet',skillSet) //'skills.jQuery'
Resume.find({skillSet : 2},function(err, results){
Below is the code snippet:
{
"_id" : ObjectId("56031b4353b32084651173fb"),
"uuid" : "acd06792-87c3-4b0e-827a-8bd19d7f9c03",
"creationDate" : ISODate("2015-09-23T21:36:03.728Z"),
"status" : "3",
"name" : "resume_dev",
"__v" : 0,
"skills" : {
"node" : 2,
"react" : 2,
"React" : 3,
"JQUERY" : 2,
"JavaScript" : 15,
"JQuery" : 5,
"Backbone" : 3,
"Node" : 2,
"Angular" : 4,
"Javascript" : 2,
"jQuery" : 17,
"javascript" : 3
}
}
router.get('/skills/:skill', function(req, res){
console.log("req.params.skill",req.params.skill);
var skillSet = ("'"+'skills.' + req.params.skill +"'");
console.log('skillSet',skillSet) //skills.react
Resume.find({skillSet : 2},function(err, results){
console.log('hi');
console.log(skillSet)
console.log(results);
if (err) {
res.status(500).json(err);
}
else {
// console.log("====>",results);
res.status(200).json(results);
// res.render('status',{Resume: JSON.stringify(results)});
}
});
});
When I understand your question correctly, you can do something like this:
var query = {};
query['skills.' + req.params.skill] = 2;
Resume.find(query,function(err, results){
// Do something with the callback
};
EDIT:
If you want to get all numbers greater or equal to 1, you will need $gte. Here are the docs. This is the updated query:
var query = {};
query['skills.' + req.params.skill] = {$gte: 1};
Resume.find(query,function(err, results){
// Do something with the callback
};

using mongodb with express to get data from database

I'm just starting out with express, node, and MongoDB and I seem to be experiencing a bit of a problem getting data from mongo in node/express.
I have a database called testdb with a collection called tests and here is the output of tests
{
"_id" : ObjectId("5395f91ced382cec1f8d70f1"),
"name" : "CHATEAU DE SAINT COSME",
"year" : "2009",
"grapes" : "Grenache / Syrah",
"country" : "France",
"region" : "Southern Rhone",
"description" : "The aromas of fruit and spice...",
"picture" : "saint_cosme.jpg"
}
{
"_id" : ObjectId("5395f91ced382cec1f8d70f2"),
"name" : "LAN RIOJA CRIANZA",
"year" : "2006",
"grapes" : "Tempranillo",
"country" : "Spain",
"region" : "Rioja",
"description" : "A resurgence of interest in boutique vineyards...",
"picture" : "lan_rioja.jpg"
}
in routes\index.js I have this
var express = require('express');
var router = express.Router();
var mongo = require('mongodb');
var db = new mongo.Db('testdb', new mongo.Server('localhost',27017),{auto_reconnect:true,safe:false});
var testData = db.collection('tests');
/* GET home page. */
router.get('/', function(req, res) {
testData.find().toArray(function(e,doc){
if(e){
throw e;
}
console.log(doc);
});
res.render('index', { title: 'Express' ,docs:"is jade cool?"});
});
module.exports = router;
as it stands the toArray callback doesn't seem to get called (console.log is not executed and no error is thrown).
if I place res.render in the toArray callback my app hangs in the browser.
since this is my first express app I'm sure I'm making a noob mistake.
I know toArray is async, but it should have been called eventually (and a console log or error should have shown in the terminal)
does anyone know why toArray is not working?

Mongodb/Mongoose: Storing Subdocument of a Variable to a Variable

I am trying to create a shotgun npm command for deleting all topics ever created by a user
This is a sample user entry (users are stored in a collection called 'users'):
{
"__v" : 0,
"_id" : ObjectId("536c4c8fafec055606f01840"), //the id I want to store to a variable and use the variable to find all topics with that id in the 'creator' document
"joinDate" : ISODate("2014-05-09T18:13:28.079Z"),
"lastActiveDate" : ISODate("2014-05-09T18:13:48.918Z"),
"lastSocketId" : null,
"password" : "Johndoe6",
"roles" : [],
"username" : "johndoe6"
}
This is a sample topic entry (topics are stored in a collection called 'topics'):
{
"__v" : 4,
"_id" : 202, //unreliable as these change all the time
"body" : "example topic text",
"commentCount" : 0,
"creator" : ObjectId("536c4c8fafec055606f01840"), //this is the id I want to be found with my variable from a found user
"date" : ISODate("2014-05-14T13:58:13.668Z"),
"editedBy" : ObjectId("536f0392ca01fb0e39364c02"),
"editedDate" : ISODate("2014-05-14T13:59:27.607Z"),
"lastCommentDate" : ISODate("2014-05-14T13:58:13.670Z"),
"tags" : [],
"title" : "test",
"views" : [],
}
Here is a snippet of my code:
exports.invoke = function (shell, options) {
if (!options.confirm) {
shell.warn("Are you sure you want to delete all topics made by {{0}}? (Y/N)".format(options.username));
return shell.setPrompt('confirm', 'purgeTopic', options, 'Are you sure?');
}
shell.db.User.findOne({ username: options.username }, function (err, user) {
var userid = something //this is where I want it to pluck out the user's ID and store it for later
if (err) return shell.error(err);
if (!user) return shell.error("No user {{0}} exists.".format(options.username));
//otherwise
shell.db.Topic.where('creator').equals(userid).remove(function (err) {
As you can see, options.username is a variable that has been typed in by the user doing the command. On the last line I want it to remove topics that have a subdocument 'creator' with the id of the 'user'. How can this be accomplished?
It would simply be:
var userid = user._id;
But you'd want to put that after your if (!user) check in case user is null.

Categories

Resources