I am using node app, i created a mongodb named as "staff" in my db. while i use and see my terminal that show the data availabilty ( 1 data i inserted ), but when i return the same using node function, i am always getting empty array('[]')..
here is my node functions:
var
appRoot = __dirname,
express = require("express"),
path = require("path"),
mongoose = require("mongoose"),
app = express();
mongoose.connect('mongodb://localhost/myOffice'); //i am connecting to myOffice db
var colligue = mongoose.model('staff', new mongoose.Schema({
name : String
}));
app.configure(function(){
app.use(express.json());
app.use(express.urlencoded());
app.use(app.router);
app.use(express.static(path.join(appRoot, "public")));
});
app.get('/', function (req, res){
res.send("I am hearing!");
});
app.get('/staff', function(req, res) {
res.sendfile(__dirname + '/public/static.html');
});
app.get('/api/staffs', function(req, res) {
return colligue.find(function(err, staffs) {
if (!err) {
return res.send(staffs); // finding from colligue but always getting empty array '[]'
}
})
});
app.listen(3000);
in the terminal i can view my data:
db.staff.find()
{ "_id" : ObjectId("52c16190b5832172661967ba"), "name" : "servent1" }
By default, Mongoose pluralizes (and lower-cases) your model name to determine the collection name it's tied to. So in this case it would use staffs instead of staff.
To fix this, you can explicitly set the collection name using the third parameter to mongoose.model:
var colligue = mongoose.model('staff', new mongoose.Schema({
name : String
}), 'staff');
Related
I am trying and failing to delete an object from a mongo collection that I created. I can make get and post requests just fine, but I am totally lost as to how to delete an item from a given collection. I am currently just deleting the entire collection when trying to pass in the item by id...
Just so you can see what I am working with...
/**** IMPORTS *****/
const express = require('express');
const cors = require('cors');
const monk = require('monk');
const app = express();
const db = monk('localhost/att');
// Mongo Collection packs holds package objects
const packs = db.get('packages');
app.use(cors());
app.use(express.json());
And my back-end delete path:
//packs is my collection
app.delete('/packages/:id', (req, res) => {
packs.remove({"_id": req.body.id});
});
and my function on the front-end:
function listAllPackages() {
fetch(API_URL_PACKAGES).then(response => response.json()).then(packageObjs => {
// Access to all the package objects in DB here
// packageObjs : Array of Packages
let html = '';
packageObjs.forEach(p => {
html += `<option id="${p._id}" name="${p._id}">${p._id} - Name: ${p.name}, Price: ($)${p.price}, Duration: ${p.duration}(minutes)</option>`;
});
allPackages.innerHTML = html;
const delPackageDiv = document.querySelector('.deletePackage');
delPackageDiv.innerHTML = `<button id='deletePackageSubmit'>DELETE PACKAGE</button>`;
const delPackageButton = document.querySelector('#deletePackageSubmit');
delPackageButton.addEventListener('click', () => {
// GET SELECTED PACKAGE
const delForm = document.querySelector('.showPackages');
const opt = delForm.options[delForm.selectedIndex];
fetch(API_URL_PACKAGES + '/' + opt.id, {
method: 'DELETE'
});
});
});
}
Figured it out finally! Here's my solution in case anyone else is struggling like I was...
Change this:
//packs is my collection
app.delete('/packages/:id', (req, res) => {
packs.remove({"_id": req.body.id});
});
To this:
//packs is my collection
app.delete('/packages/:id', (req, res) => {
packs.remove({"_id": req.params.id });
});
Voila!
Creating a small web app on the MEAN stack and I'm in the process of migrating my schemas to a separate "models" directory. When the schemas are defined in the same app.js file, everything works fine; however, when I switch the code to a separate more modular file and import it I get this error:
TypeError: Player.find is not a function
at /Users/username/code/express/WebApp/v3/app.js:57:12
This error occurs when it gets to that first route where it needs to look players up and I'm not quite sure what I'm missing after staring at this for hours.
My app.js file:
var express = require("express"),
app = express(),
bodyParser = require("body-parser"),
mongoose = require("mongoose"),
Player = require("./models/players")
const port = 3000;
mongoose.connect("mongodb://localhost/players", { useNewUrlParser: true, useUnifiedTopology: true });
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({extended: true}));
// PLAYER SCHEMA ORIGNALLY DEFINED HERE BUT NOW ATTEMPTING TO MOVE TO DIFF DIRECTORY & IMPORT
/*var playerSchema = new mongoose.Schema({
player: String,
position: String,
description: String
});
var Player = mongoose.model("Player", playerSchema);*/
app.get("/", function(req, res) {
res.render("landing");
});
app.get("/players", function(req, res) {
// Get all players from DB
Player.find({}, function(err, allPlayers){
if(err){
console.log(err);
} else {
console.log("We're good.");
res.render("players", {players: allPlayers});
}
});
});
and my player.js file that I'm attempting to import:
var mongoose = require("mongoose");
var playerSchema = new mongoose.Schema({
player: String,
position: String,
description: String
});
// Compile into a model
module.exports = mongoose.model("Player", playerSchema);
The above schema definition and model definition work completely fine when they're in the app.js file, but not when imported. What am I missing here? Thanks in advance for the help.
I think your file name is wrong at the require statement. Its
const Player = require('../models/player')
as your file name is player.js, not players.js and if you stored the js file in a model folder. Do check out how to navigate using the file path
/ means go back to the root folder, then traverse forward/downward.
./ means begin in the folder we are currently in and traverse forward/downward
../ means go up one directory, then begin the traverse.
And also your backend should look like this.
Backend File Management
I am using mongo with node.js, I am using mongodb npm package to connect with db and my code as follows.
var express = require('express');
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/STUDENT";
var app = express();
MongoClient.connect(url, function(err, db) {
console.log("Connected correctly to server");
findDOcuments(db);
db.close();
});
var entireDoc = '';
var data = function(data, id){
if(id == 'records'){
entireDoc = JSON.stringify(data);
}
}
var findDOcuments = function(db) {
// Get the records collection
var collection = db.collection('records');
// Find some records
collection.find({}).toArray(function(err, docs) {
console.log("Found the following records");
console.log(docs);
data(docs,'records');
});
}
app.get('/getInfo', function(req, res){
res.render(entireDoc);
})
app.listen(3000);
The above code while rendering in browser throwing the above error in the browser. Can any one help in this.
You need to specify express what typ eof view engine you are working with. for example ejs, jade, pub, handlebars or plain html..
Add following in your code below middlewares :
// views directory will be project_folder/views. So basically when you give a template file name to render, it should know where to find this. So below path is set.
app.set('views', path.join(__dirname, 'views'));
//specify view engine and also to use it you need to install like npm install --save ejs
app.set('view engine', 'ejs');
So when you say res.render('products');
It will search for a product.ejs file inside project_folder/views/
Further if you want to send direct string, you can use res.send() or if you want to send json, you can use res.json(). Render is used to render a view template from view engine
app.use(
express.static(path.join(__dirname, 'public'), {
etag: false
})
);
I have a MongoDb server hosted on Azure. I'm now building a Node.js API meant to retrieve data from a table on one of the databases (i.e. table: Word; database: MyDatabase). I've built the API following this tutorial, but I'm unable to successfully retrieve any data from it...
I know the server is up and running and also reachable since I can tcp-connect to it through:
psping [Azure's Public IP]:27017
Now, I have an node.js api with the following code:
1) app/server.js
var express = require('express'); // call express
var app = express(); // define our app using express
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.connect('mongodb://[Azure's public IP]:27017/MyDatabase');
var Word = require('./models/word');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080; // set our port
// ROUTES FOR API
var router = express.Router(); // get an instance of the express Router
// middleware to use for all requests
router.use(function(req, res, next) {
// do logging
console.log('Something is happening.');
next();
});
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
router.route('/words')
.get(function(req, res) {
Word.find(function(err, words) {
if (err)
res.send(err);
res.json(words);
});
});
// more routes for our API will happen here
// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
app.use('/api', router);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);
I've also written a model for my only table within the database, which has 3 columns: the auto-generated ObjectId, Spanish, French (meant to have words in both languages to make it work as a translator). The models looks like this: 2) app/models/word.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var WordSchema = new Schema({
spanish: String,
french: String
})
var Word = mongoose.model('Word',WordSchema);
module.exports = Word;
Now, I go to postman and GET on the following: http://localhost:8080/api/words; which returns [].
On MongoDb logs I see the following:
2016-08-05T03:16:26.520+0000 I NETWORK [conn60] end connection [Some IP]:[Some port] (1 connections now open)
2016-08-05T03:31:11.878+0000 I NETWORK [initandlisten] connection accepted from [Some IP]:[Some port] #61 (1 connection now open)
As you mentioned in your comment that the documents were retrieved from db.word.find() I think I found the problem. You need to put documents into collection named words, instead of word.
Mongoose will use the plural version of your model name. See http://mongoosejs.com/docs/models.html for more information.
I think you are missing {} when doing find.
router.route('/words')
.get(function(req, res) {
Word.find({}, //Added here.
function(err, words) {
if (err)
res.send(err);
console.log(words)
res.json(words);
});
});
Hope this will help.
EDIT:-
According the document of doc, the find function accept the first parameter as an object and treat it as conditions, but not a callback function.
I am receiving an empty array with the following code:
var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'mytestapp');
var SurveySchema = require('../models/Survey.js').SurveySchema;
var Survey = mongoose.model('SurveySchema', SurveySchema, 'surveys');
var UserSchema = require('../models/Survey.js').User;
var User = mongoose.model('user', UserSchema, 'users');
exports.getSurveysForUser = function(User) {
return function (req, res) {
User
.findOne({_id: req.params.userId})
.populate('surveys')
.exec(function (err, user){
if (err) return res.json({error: err})
else {
var surveyList=[];
surveyList = user.surveys;
console.log(surveyList);
console.log("user: "+ user);
res.json(surveyList);
}
});
}};
This is the console output:
[ ]
user: { __v: 2,
_id: 52939b8c22a7efb720000003,
email: 'a#b.de',
password: '202cb962ac59075b964b07152d234b70',
surveys: []
}
These are the Mongoose models:
exports.SurveySchema = new Mongoose.Schema({
description : String,
questions : [question] });
exports.User = new Mongoose.Schema({
name : String,
email: { type: String, unique: true },
password: { type: String, required: true},
surveys : [{type: Schema.ObjectId, ref: 'SurveySchema'}] });
Btw:
I already tried User.findOne(...) and then a Survey.find() in the callback. It seemed that the second statement was not even executed. Apparently i am very new to mongoose..and i can't find a way around this problem
Do you have any ideas how to help me?
I couldn't really find any helpful solution here, but the problem shouldn't be a big one.
Thanks in advance, its really keeping me up for days now!!
Edit: So this is the index.js with the method:
var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'mytestapp');
var SurveySchema = require('../models/Survey.js').SurveySchema;
var Survey = mongoose.model('SurveySchema', SurveySchema, 'surveys');
var UserSchema = require('../models/Survey.js').User;
var User = mongoose.model('user', UserSchema, 'users');
//.. here are some more methods..
exports.getSurveysForUser = function(User) {
return function (req, res) {
User
.findOne({_id: req.params.userId})
.populate('surveys')
.exec(function (err, user){
if (err) return res.json({error: err})
else {
var surveyList=[];
surveyList = user.surveys;
console.log(surveyList);
console.log("user: "+ user);
res.json(surveyList);
}
});
}};
//this is the code, that saves a response to a survey
exports.addResponse = function(ResponseSet) {
return function (req, res) {
console.log("bin da: addResponse");
console.log("response zu: " + req.body.surveyId);
console.log("von user : " + req.body.userId);
//für user speichern
var pUser = User.findOne({_id:req.body.userId}, function (error, user) {
// Maybe populate doesnt work, because i only push the ID?
user.surveys.push(Mongoose.Types.ObjectId(req.body.surveyId));
user.save();
}
);
var pSurvey = Survey.findOne({_id:req.body.surveyId}, function (error, survey) {
survey.responses.push(Mongoose.Types.ObjectId(req.params.id));
survey.save();
}
);
//responseSet speichern
var responseSet = new ResponseSet(req.body);
responseSet.save(function(error, responseSet) {
if (error || !responseSet) {
res.json({ error : error });
} else {
res.json(responseSet);
}
});
};
};
And this is the app.js, which consumes the index.js:
var Mongoose = require('mongoose');
var db = Mongoose.createConnection('localhost', 'mytestapp');
var SurveySchema = require('./models/Survey.js').SurveySchema;
var Survey = db.model('surveys', SurveySchema);
var UserSchema = require('./models/Survey.js').User;
var User = db.model('user', UserSchema);
var ResponseSetSchema = require ('./models/Survey.js').responseSet;
var ResponseSet = db.model('responseSet', ResponseSetSchema);
var express = require('express')
, routes = require('./routes')
, http = require('http')
, path = require('path')
, passport = require('passport')
, pass = require('./config/pass')
, user_routes = require('./routes/user');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views/app');
//app.engine('html', require('ejs').renderFile);
app.use(express.static(__dirname + '/views/app'));
app.use(express.cookieParser());
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({ secret: 'securedsession' }));
app.use(passport.initialize()); // Add passport initialization
app.use(passport.session()); // Add passport initialization
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.all('/secure', pass.ensureAuthenticated);
app.get('/', function (req, res)
{
res.render('index.html');
} );
// some more code...
app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser(User));
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Hope it helpsto fight the problem!
Many many thanks in advance!! :)
Try changing:
surveys: [{type: Schema.ObjectId, ref: 'SurveySchema'}] });
to
surveys: [{type: Schema.Types.ObjectId, ref: 'SurveySchema'}] });
Also, make sure you have surveys pushed as children to User.surveys.
http://mongoosejs.com/docs/populate.html, here this section talks about your requirement in detail:
Refs to children
We may find however, if we use the aaron object, we are unable to get a list of the stories. This is because no story objects were ever 'pushed' onto aaron.stories."
Ok, it took quite a lot to figure out the issue:
exports.getSurveysForUser = function(User) {
...
};
The var User - model is not being injected into the scope properly. Change to:
exports.getSurveysForUser = (function(User) {
...
})(User);
The returned function's signature for middleware do not require User model to be passed as they are re-initiated and passed within the middleware code.
In index.js, change this
app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser(User));
to
app.get('/api/secure/userSurveys/:userId', routes.getSurveysForUser());
I also request you to self test your code and read as many docs as possible. Also, there can be multiple ways of reaching your goals. With time and practice you will conquer them all. Good luck!
So i found a solution!
Firstly it seemed, that the mongoose Schemas were not correctly required.
So in the models, i did mongoose.model('modelname', schemaname); for every model and now i only use mongoose.model(...) for every model in the index.js.
Secondly i found out about an even more critical thing: There were suddenly no user.surveys for my testuser anymore! I am sure that it was filled with surveys a few days ago. Because i tested my code several times and some surveys were pushed to that collection. Maybe i dropped the collection it in some testing..i don't really remember. So i pushed a survey manually in the mongodb console and tested it again --> worked! the user.surveys were populated! maybe the function worked yesterday and didn't need any change. I am so sorry, if that was a waste of time.
Bad thing is, that right now the exports.addResponse(....) is only saving a response, but is not pushing the IDs to the arrays user.surveys and survey.responses. This seems to be a synchronizing Problem and i will figure that out somehow.
Anyways, thank you for your help and time!