what's wrong with this model - javascript

I need to develop a module for getting data from mongodb, I already have other models working in my application, but this one does not, this is my schemas:
var mongoose = require('mongoose');
var ProvinciaSchema = new mongoose.Schema({
"nome":String,
"tc_provincia_id":Number,
"id" : Number,
"codice_regione" : Number,
"codice" : Number,
"sigla" : Number
},{collection:'province'})
module.exports = ProvinciaSchema;
this is my model:
var mongoose = require('mongoose');
var ProvinciaSchema = require('../schemas/provincia');
var Provincia = mongoose.model('provincia', ProvinciaSchema);
module.exports = Provincia;
This is how I use the model:
var Provincia = require('../../models/provincia');
Provincia.find({},next( err, province){
if (err){console.log('errorre whoosh '+err);
return next(err,province)
}
if (!province){console.log('trovato nulla')}
console.log('callback tc_istat_id')
return next(err,province)
})
where
next =function(err,prov){
t.equivalent(out,expect)
t.end()
when I launch the test if the condition argument is correct, the execution stuck at Provincia.find and the callback function it is not executed, if I put a wrong condition the section of the code of if(err) is executed, I think there is a problem with my schemas abnd models, but I do not understand what.

function myFunction(callback) {
Provincia.find({},next( err, province){
if (err) {
console.log('errorre whoosh '+err);
return next(err,province)
}
if (!province){
console.log('trovato nulla');
return false;
}
console.log('callback tc_istat_id')
callback(err,province)
})
}
myFunction(function(err,prov){
t.equivalent(out,expect)
t.end()
});
I had no way of testing this but it is how I would set up my callback function. Let me know what you log, and what errors your get if this does not work

Related

My .find function is not calling my database

My .find function is not working. It is not calling my database and returning an error of:
TypeError: beerSchema.findOne is not a function
My other pages display fine, it is just the page, I am trying to load the database on.
app.get("/beers", function(req, res){
//Get all beers
beerSchema.find({}, function(err, beers){
if (err) {
console.log(err);
} else {
res.render("beers", {beers: beers});
}
});
});
BeerSchema:
var beerSchema = new mongoose.Schema({
name:String,
abv: Number,
type:String,
Brewery:String,
Image:String
});
var beer = mongoose.model("Beer", beerSchema );
I get the error that .find is not a function.
You need the model not the schema. Wherever you're making your schema, change this:
module.exports = beerSchema;
To this:
module.exports = mongoose.model("Beer", beerSchema);
Then import this in your app file:
const { Beer } = require("./beer.js");
And use Beer:
Beer.find({}, function(err, beers) {...});
Side note: ES6 shorthand property notation means instead of this:
res.render("beers", { beers: beers });
You can just do:
res.render("beers", { beers });

Querying mongoose to perform a join

I have 2 collections setup as below, Dates and Streets.
What I would like to achieve is to, query Streets by a param StreetName and look that up to find it's unique ID and then query the other collection by that ID to pull back all the dates that match.
My route is set up to /wasteDate/:StreetName. Here's what I have:
model.js
var DateSchema = new Schema({
date: {
type: Date
},
street_id: {
type: String,
}
});
var StreetSchema = new Schema({
name: {
type: String
}
});
routes.js
module.exports = function(app) {
var wasteCollections = require('../controllers/wasteController');
app.route('/wasteDate/:streetName')
.get(wasteCollections.get_dates_by_street_name);
};
controller.js
var mongoose = require('mongoose'),
ColDate = mongoose.model('Dates'),
that = this,
Street = mongoose.model('Streets');
(...)
exports.manual_get_dates_by_street = function (id) {
var wasteDates = ColDate.find({ street_id: id }).lean();
return wasteDates;
};
exports.get_dates_by_street_name = function (req, res) {
Street.find({
name: req.params.streetName
}, function(err, street) {
var query;
var theStreetId = street[0].id;
if (err) res.send(err);
query = that.manual_get_dates_by_street(theStreetId);
res.json(query);
});
};
at the moment i'm getting a circular reference error on the JSON.
I don't think I'm doing it the right way and think I may need to amend my schema?
Any help appreciated
You can either use (1) find twice or (2) aggregation.
Here's the first way:
exports.manual_get_dates_by_street = function (id, callback) {
// you are dealing with asynchronous operations, so you have to wait for the callback
// to execute before you can get the data
ColDate.find({ street_id: id }).lean().exec(callback);
};
exports.get_dates_by_street_name = function (req, res) {
// you are expecting one result, so use findOne instead of find
Street.findOne({ name: req.params.streetName }, function (err, street) {
// make sure you handle errors properly such as stopping execution of
// the next lines or else you may get unexpected errors
if (err)
return res.send(err);
// we pass a callback that will be executed once results (or an error) are found
that.manual_get_dates_by_street(street._id, function (err, dates) {
res.json({ dates: dates });
});
});
};
I never used it but I think mongoose-models may resolve your problem. https://github.com/SportZing/mongoose-models
Another possible approach is to put the second query function as a callback of the first.

Mongoose save : saving failed without error

I'm building a simple app with mongoose to save some data from an IRC channel.
I have a remote database on a OVH VPS where I can access and log-in without any problems.
However when I try to save some data on it I can't go it with my javascript code.
Here is the data I would like to save :
"use strict"
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
var UserPointDataSchema = new Schema({
username: String,
value: Number,
channel: String,
timestamp: Number
});
var UserPointDataModel = mongoose.model('UserPointData',UserPointDataSchema);
class UserPointData{
constructor(username,value,channel){
this.username = username;
this.value = value;
this.channel = channel;
this.timestamp =Date.now();
this.mongooseModel = this.toMoogoseModel();
return this;
}
toMoogoseModel(){
return UserPointDataModel.hydrate(this);
}
save(){
this.mongooseModel.save(function (err, product, numAffected) {
if (err){
console.log(err);
}
console.log(err);
console.log(product);
console.log(numAffected);
});
}
}
module.exports = UserPointData;
Here is the output on the console :
null
{ username: 'breci', value: 1, channel: 'breci', timestamp:
1478897691976 }
0
MongoDB version : 3.2.10
Mongoose version : 4.6.6
I checked the logs, no identification problem, no error too.
Someone has an idea why it is not working ?
Solved it by changing the toMongooseModel() method
Here is the new one if someone has the same problem need it :
toMoogoseModel(){
var data = {
username :this.username ,
value: this.value,
channel: this.channel,
timestamp: this.timestamp
}
var res = new UserPointDataModel(data);
return res;
}
If anyone know why the hydrate method didn't work I'm curious to know.

outsource XXX.db.bson_serializer.ObjectID.createFromHexString(id) to a function?

I went through this express tutorial. I was wondering if it is possible to outsource the following call to a separate function, as it is very very long?
employee_collection.db.bson_serializer.ObjectID.createFromHexString(id)
This is the whole file where the statement is called:
var Db = require('mongodb').Db;
var Connection = require('mongodb').Connection;
var Server = require('mongodb').Server;
var BSON = require('mongodb').BSON;
var ObjectID = require('mongodb').ObjectID;
EmployeeProvider = function(host, port) {
this.db = new Db(
'node-mongo-employee',
new Server(host, port, {}),
{safe: true}
);
this.db.open(function(){});
};
...
// find an employee by id
EmployeeProvider.prototype.findById = function(id, callback) {
this.getCollection(
function(error, employee_collection) {
if( error )
callback(error)
else {
employee_collection.findOne(
{_id: employee_collection.db.bson_serializer.ObjectID.createFromHexString(id)},
function(error, result) {
if( error )
callback(error)
else
callback(null, result)
}
);
}
}
);
};
...
exports.EmployeeProvider = EmployeeProvider;
It's the controller of an express application. It's shortened, but should give you an idea of what it does. You can find the whole application on Github.
I tried
getid = function( employee_collection, id ) {
return employee_collection.db.bson_serializer.ObjectID.createFromHexString(id);
};
and called the function with
{_id: getid(employee_collection, id),
but I'm getting a very long ENOENT error with that one.
Presuming that you are working with the basic node.js mongodb driver here and that you have id essentially coming in as something like a request parameter, which means it's just a string and looks something like:
"53cfba87e248860d16e1f7e1"
Then the import you have used here:
var ObjectID = require('mongodb').ObjectID;
Gives you a direct function to use. Just do this:
employee_collection.findOne({ "_id": ObejctID(id) },function(err,result) {
// work in here
});
The ObjectID you are importing already implements this function.

Assign property value doesn't work in Mongoose

My query is:
db.Room.find({}, function (err, rooms) {
if (!err) {
async.each(rooms, function (room, done) {
db.User.find({}, function (err, users) {
if (err) {
done(err)
} else {
room.users = users
room._name = room.name
done()
}
})
}, function (err) {
if (!err) {
socket.emit('read:rooms', rooms)
}
})
}
})
and schemas are:
room:
var mongoose = require('mongoose')
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var Room = new Schema({
name: String
});
module.exports = Room
user:
var mongoose = require('mongoose')
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var User = new Schema({
email: String
});
module.exports = User
but in front-end:
socket.on('read:rooms', function (rooms) {
$scope.rooms = rooms
})
but rooms has no users property, help me, please
It's because the Rooms schema doesn't have a users property.
So, there are a few ways to fix it. Since it looks like though you want the users property to be something that really isn't part of the schema, and is a client-side join rather than work that is done on the database (which is a good!), I'd suggest you convert the data to be just plain old JavaScript objects when you send it over the socket (this would have happened anyway, you're just doing it a bit earlier).
So, when the find returns, it is actually returning a fully-realized MongooseJS model object. While you can set dynamic properties on the object instance, they aren't part of the "data" of the model, so that when it is serialized later to the client, only the properties that are documented will be available.
So, here is an example of what I'd suggest:
db.Room.find({}, function (err, rooms) {
if (!err) {
var oRooms = [];
async.each(rooms, function (room, done) {
/* etc. your code */
} else {
var oRoom = room.toObject();
oRoom.users = users
oRoom._name = room.name
oRooms.push(oRoom);
done()
}
This technique would use the toObject functionality of a Model to return a JavaScript object (not a Mongoose model). That way, you can do what you'd like to the object, including adding new properties dynamically.
Later, of course, make sure you send the new array of rooms to the client:
if (!err) {
socket.emit('read:rooms', oRooms)
}

Categories