jedireza / hapi-mongo-models Goto Github PK
View Code? Open in Web Editor NEW:package: A hapi plugin for `mongo-models`
License: MIT License
:package: A hapi plugin for `mongo-models`
License: MIT License
Would something like this be possible to call from server.start()?
const server = new Hapi.Server();
...
server.start( function() {
const Game = server.plugins['hapi-mongo-models'].Game;
Game.find( {}, function( err, result ) {
console.log( result );
});
});
Error:
.../node_modules/hapi-mongo-models/lib/base-model.js:259
const collection = BaseModel.db.collection(this._collection);
^
TypeError: Cannot read property 'collection' of undefined
Hi, I'm new to HAPI and need some notion of models in our new project. We come from using SailsJS which offers some notion of Associations with the use of Waterline. Does your plug-in offer us the ability to have associations and specifically the ability to populate an associated child model?
I have two questions relative to this issue.
for example: if I have below schema, SurrogateData collection will store 'san' which is a value being used to replace pan (real credit card number according to EMVCo spec.). The san itself should not be duplicated!
SurrogateData.schema = Joi.object().keys({
_id: Joi.object(),
san: Joi.string().regex(/^\d{16}/).length(16).required(),
expr: Joi.string().regex(/\d{4}/).length(4).required(),
// ManyToOne
primary_data: Joi.object().keys({
id: Joi.string().required(),
pan: Joi.string().regex(/\d{13,19}/).required()
}).required()
}).required();
Is it correct to use below technique to achieve this?
SurrogateData.indexes = [
[{ san: 1 }]
];
a. generateSan()
b. checkDuplicated() (if duplicated then go to step a)
c. insert()
Hi,
I have found an interesting issue, I thought I would mention it here.
On line https://github.com/jedireza/hapi-mongo-models/blob/master/lib/base-model.js#L244 my find methond worked onny if I replaced the above line with this:
var callback = args.pop();
I am not sure why the original line doesn’t work, but the symptom is that it returns a good result with one issue: elements in the data array are all empty objects.
Happy to provide more details if needed.
So far, plugin is already registered:
// AdminModel.js
var Admin = require('hapi-mongo-models').MongoModels;
Admin.indexes = [{
key: {
username: 1
},
unique: true
}, {
key: {
email: 1
},
unique: true
}];
Admin.collection = 'admins';
Admin.schema = validation;
Admin.findByUsername = function(username, callback) {
var filter = {};
this.find(filter, callback);
};
// other.js
var admin = require('AdminModel');
admin.findByUsername('someUser', function(err, res) {
console.log(res);
});
And the result is:
MongoModels {
_id: 58490c05aa6bbf587f55951d,
username: 'someUser',
password: '123456',
user_type: 'admin' }
I have updated from v5.0.1 to v6.0.0 and fixed the breaking changes but with no luck. Pretty sure that i'm doing something wrong but can't figure out what it is.
In /lib/base-model.js
we need to be catching errors thrown when casting values with _idClass
and execute the callback
with the error.
These lines:
hapi-mongo-models/lib/base-model.js
Line 273 in 6f36897
hapi-mongo-models/lib/base-model.js
Line 290 in 6f36897
hapi-mongo-models/lib/base-model.js
Line 302 in 6f36897
The following query does always return an empty array
Model.find( { '_id': { $in: [ '4ed3ede8844f0f351100000c', '4ed3f117a844e0471100000d' ] }} );
Migrating from Hapi 14 to 17.6, any idea why below isn't working?
Doesn't work:
models: [
'./models/user'
],
Works:
models: [
'/home/Hapi17/models/user'
],
Not sure where the issues arise from, but
e.g In a document I have stored an array with 100 card objects, I only desire to pull one card with id:20 from that document
From console 3.6, this do exactly that:
db.myCards.findOne({ user_id: x }, { cards: { $elemMatch: { id: 20 }}} );
But, from latest hapi-mongo-models, same line will return all cards in the array
Hi
Where does the joi validation occur? I can see the function created in base model class but can't see where it is used?
Thanks
Simon
It seems that for some reason we are unable to update a model. No issues with creating, finding, etc.
Using something as simple as the following code, yields a count = 0:
Company.updateOne({ _id: '57c9a2894160eb694371d69d' }, { $set: { name: 'TEST' } }, (err, count) => {
if(err){
return reply(Boom.wrap(err, 500));
}
reply({ count: count });
});
Is there something that is being overlooked here? I've also looked at the test code and everything seems to be lined up correctly.
Seems to me, like Model.insertOne() will return an array with 1 object, instead of just the object.
Have you considered returning Promises? I have found Promises very handy when dealing with db layer. It usually results in cleaner, more obvious code (imho).
Refer the log
Uncaught error: Cannot read property 'collection' of undefined, stack: TypeError: Uncaught error: Cannot read property 'collection' of undefined.
TypeError: Uncaught error: Cannot read property 'collection' of undefined
< at Function.insertOne (/Users/mohitmehta/Documents/repository/server/src/albums/node_modules/mongo-models/index.js:449:42)
< at Function.create (/Users/mohitmehta/Documents/repository/server/src/albums/models.js:15:12)
The complete log is:
< 170811/052500.156, [error] message: Uncaught error: Cannot read property 'collection' of undefined, stack: TypeError: Uncaught error: Cannot read property 'collection' of undefined
< at Function.insertOne (/Users/mohitmehta/Documents/repository/server/src/albums/node_modules/mongo-models/index.js:449:42)
< at Function.create (/Users/mohitmehta/Documents/repository/server/src/albums/models.js:15:12)
< at Controller.albums (/Users/mohitmehta/Documents/repository/node_modules/hapi-albums-api/controllers.js:22:15)
< at Object.internals.handler (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/handler.js:101:51)
< at request._protect.run (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/handler.js:32:23)
< at internals.Protect.run (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/protect.js:60:12)
< at exports.execute (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/handler.js:26:22)
< at each (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/request.js:416:16)
< at iterate (/Users/mohitmehta/Documents/repository/node_modules/items/lib/index.js:36:13)
< at done (/Users/mohitmehta/Documents/repository/node_modules/items/lib/index.js:28:25)
< Debug: internal, implementation, error
< TypeError: Uncaught error: Cannot read property 'collection' of undefined
< at Function.insertOne (/Users/mohitmehta/Documents/repository/server/src/albums/node_modules/mongo-models/index.js:449:42)
< at Function.create (/Users/mohitmehta/Documents/repository/server/src/albums/models.js:15:12)
< at Controller.albums (/Users/mohitmehta/Documents/repository/node_modules/hapi-albums-api/controllers.js:22:15)
< at Object.internals.handler (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/handler.js:101:51)
< at request._protect.run (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/handler.js:32:23)
< at internals.Protect.run (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/protect.js:60:12)
< at exports.execute (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/handler.js:26:22)
< at each (/Users/mohitmehta/Documents/repository/node_modules/hapi/lib/request.js:416:16)
< at iterate (/Users/mohitmehta/Documents/repository/node_modules/items/lib/index.js:36:13)
< at done (/Users/mohitmehta/Documents/repository/node_modules/items/lib/index.js:28:25)
< 170811/052500.156, [response] http://127.0.0.1:3000: get /api/v1/albums {} 500 (9573ms)
Can a mongodb custom logger be implemented to switch the Mongo logger to server.log? Also would need a logLevel option.
http://mongodb.github.io/node-mongodb-native/2.0/tutorials/logging/
goal would be to provide the option logLevel: "debug" and then mongodb would use server.log to log to the console in mongodb debug mode.
new to hapi so if there is a better way to accomplish this let me know.
I noticed that you often use
var args = Array.prototype.slice.call(arguments);
According to this docs it prevents optimization of such function.
Btw very cool project, I was missing something between native-mongodb and mongoose and ideally with Joi validation :-).
I'm trying to use the positional operator but this doesn't seem to work. Any help appreciated!
var update = {
$inc: {
resellers.$.inventory: 1
}
};
Product.findOneAndUpdate({_id : 1234,'resellers._id': 'zxcv'}, update, function (err, product) {
if (err) {
reply(err);
}
reply(product);
});
//_id: 1234,
//product: "ShamWow Blue Edition",
//resellers: [
// {
// _id : zxcv,
// inventory: 23
// },
// {
// _id: asdf,
// inventory: 51
// } ,
// (etc)
//]
ensureIndex
is being depricated:
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#ensureIndex
We should use createIndexes
instead:
http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#createIndexes
Docs for the indexSpecs
argument can be found here:
http://docs.mongodb.org/manual/reference/command/createIndexes/
We should:
ensureIndexes
and ensureIndex
from BaseModel
ensureIndexes
and ensureIndex
createIndexes
in BaseModel
that accepts indexSpecs
as an argument or looks at the static property on the model (like it is today).createIndexes
functionWill this plugin be supported in hapi v17? It's listed as an official plugin in the hapi website.
I got below document schema. However, I can still insert document without some keys....
shouldn't that the required property declare some field that cannot be ignore?
or do I misuse the Joi class?
PrimaryAccount.schema = Joi.object().keys({ // token type
_id: Joi.object(),
type: Joi.string().required(),
credit_card: Joi.object().keys({
type: Joi.string().required(),
cardholder_name: Joi.string().required(),
card_number: Joi.string().creditCard().required(),
exp_date: Joi.date().format('MMYY'),
cvv: Joi.string().required()
}),
token: Joi.object().keys({
value: Joi.string().required(),
exp_date: Joi.date().format('MMYY').required()
})
}).required();
Hi
Just a heads up Hapi 11.0 has removed server.after method.
Thanks
Simon
Hi, I want to use native aggregation methods of the mongodb library, but I can't find the way to use it through hapi-mongo-models.
Is there a way to do that?
I'm not sure if this was something you did when you made the hapi-mongo-models but you cannot insert more than 1000 length array of documents into a mongo db with your calls. I also wanted to make you aware that this plugin is running on an extremely old version of mongodb version 1.4 i believe and the current version is 2.0.25. This might be the root of the issue.
Hello,
has this plugin support for mongodb ssh tunnel ? I can't find a way to connect
Hi,
I am using this great library on production and it worked perfectly until a few days ago.
To put it simple, after some usage of the API (vary between 5 min to 20 hours), the BaseModel (hapi-mongo-models) simply timeouts on every request (that is - the callback function is not called - not even as an error).
However, if during its "stuck" mode I evaluate a JS expression (with eval) that creates a brand new mongoDB proxy (using the native 'mongodb'), it works perfectly fine (hence I think it has to do with BaseModel and the fact it is a singleton-ish).
This lead me to believe that the db's cursor itself is not being released properly.
**** The following is an assumption (based on some local code).
I have drilled down to the cursor.js file (part of the native library) and the issue seem to be around the nextObject (line 647, [email protected]), where no object nor error is being captured by the document and it seem to be entering some deadlock.
Unfortunately I can't easily reproduce it.
Any help, debugging, ideas are welcomed.
THANKS.
** I've moved to the newest frame version which did not help.
I've also opened a SW case http://stackoverflow.com/questions/37371421/hapijs-hapi-mongo-models-server-stuck-on-504-http-error
Earlier version of hapi-mongo-models had quite good examples (been using it for years), now when "forced" to migration to hapi17.6, I find myself headbanging with current release of hapi-mongo-models, special the limited information and lack of examples...
Does their exists more examples for hapi somewhere I can't find?
Is there a way to support multiple Mongo databases?
I have a document in my collection
"created_date" : ISODate("2016-05-20T04:44:08.492Z")
and when I query it from Robomongo using
find({"created_date": new Date("2016-05-20T04:44:08.492Z")})
it works ok.
When I do it from my hapi model I get zero results:
filter.created_date = new Date("2016-05-20T04:44:08.492Z");
this.find(filter, function(err, res) {
console.log("res", res); // Empty Array here!
});
Am I missing something or is it a bug? Thanks!
Tracking: jedireza/mongo-models#24
After mongo-models
get's updated, we need to get ready for hapi v17.
I would just like to know. Thanks!
https://github.com/jedireza/hapi-mongo-models/blob/master/package.json#L36
I have a document with the following format:
"_id": ObjectId("234345345"),
"name": "My name",
"friends": [
{
"id" : ObjectId("2424234234234"),
"age": 23,
"teams" : ["team 1", "team 2", "team 3"]
},
{
"id" : ObjectId("1122334455"),
"age": 28,
"teams" : ["team 4", "team 5", "team 6"]
}
]
I am attempting to update one object in the friends array using the "updateOne" method.
MyModel.updateOne({_id: ObjectID(id), "friends.id": ObjectID(friendId)},{$set: {"friends.$": friendObject} }, function (err,myModel){...}).
However, nothing is being updated. Is this an issue with the UpdateOne function or am I missing something?
If am using aggregate method on my collection it gives me error
ebug: internal, implementation, error
TypeError: Uncaught error: ClientStatus.aggregate is not a function
at server.route.config.pre.method.reply (
I'm working on an application that uses hapi-mongo-models for its CRUD operations, and I want to update a document with some nested subdocuments. In vanilla Mongo I'd query by _id to find the doc I want to update, and pass a {$set:{}} object as my update, but for some reason I can't get it to update my document (doesn't return as error, just resolves without performing any updates). The same query runs properly in a mongo shell environment.
Is $set not supported by hapi-mongo-models?
Thanks!
Chris
Hi, I was wondering if you had plans to add a .distinct method, which is available in mongodb's native driver. Thanks!
If I try to find multiple registries inside an async.each
loop, just sometimes, I get Not authorized on dbname to execute command
. If it's a security issue I should get the "Not authorized" error always but this is not the case. On the other side, I'm connecting to a vps and if I disable auth=true
from Mongo on the server it works correctly.
model.js
async.each(result, function(order, next) {
AnotherModel.findOne({shop_id: shopId}, function(err, shop) {
// Sometimes I get err, otherwise the registry
});
});
Any help ? Thanks
Hi, I'm trying to test with Lab an API that uses hapi-mongo-models
but I'm having an error:
Debug: internal, implementation, error
TypeError: Uncaught error: Cannot read property 'collection' of undefined
at Function.BaseModel.insertOne (/home/james/.../node_modules/hapi-mongo-models/lib/base-model.js:423:34)
at Function.Endpoint.create (/home/james/.../models/endpoint.js:32:92)
at server.route.handler (/home/james/.../server.js:134:90)
at Object.internals.handler (/home/james/.../node_modules/hapi/lib/handler.js:94:36)
at /home/james/.../node_modules/hapi/lib/handler.js:28:23
at internals.Protect.run (/home/james/.../node_modules/hapi/lib/protect.js:56:5)
at exports.execute (/home/james/.../node_modules/hapi/lib/handler.js:22:22)
at /home/james/.../node_modules/hapi/lib/request.js:371:13
at iterate (/home/james/.../node_modules/hapi/node_modules/items/lib/index.js:35:13)
at done (/home/james/.../node_modules/hapi/node_modules/items/lib/index.js:27:25)
at /home/james/.../node_modules/hapi/node_modules/hoek/lib/index.js:841:22
at process._tickDomainCallback (node.js:381:11)
Test file:
var Lab = require('lab');
var Code = require('code');
var server = require("../");
var lab = exports.lab = Lab.script();
var expect = Code.expect;
lab.experiment("Endpoint", function() {
lab.test("creation", function(done) {
var options = {
method: "POST",
url: "/api",
payload: {
email: '[email protected]'
}
};
server.inject(options, function(response) {
var result = response.result;
expect(response.statusCode).to.equal(200);
expect(result).to.be.an.object();
done();
});
});
});
server.js
...
handler: function (request, reply) {
var Endpoint = request.server.plugins['hapi-mongo-models'].Endpoint;
var data = request.payload;
Endpoint.create(data, function (err, res) {
if (err) {
return reply(err);
}
reply(res[0]);
});
}
...
models/endpoint.js
...
Endpoint.create = function (data, callback) {
data.date = new Date();
this.insertOne(data, callback);
};
...
The error says that there is no collection
property because BaseModel.db
is undefined in:
BaseModel.insertOne = function () {
...
var collection = BaseModel.db.collection(this._collection);
...
};
So I think I need to connect to the database first but I'm not sure about how to do it. Do you have any suggestions?
Thanks!
See: #4
Instead of defining each model with the models
option, it would be nice if I could just pass the directory I keep all my models in.
We've split the BaseModel
out into it's own repo, which makes it a more general tool outside of hapi applications. We're now exclusively using es6 classes instead of using the ampersand-class-extend
hack.
BaseModel
has moved into it's own package mongo-models
. It is also referred to as MongoModels
instead of BaseModel
.mongo-models
is a new peerDepdendency
you'll need to include in your application's package.json
.BaseModel.extend(...)
is gone. Simply extend with es6 class Customer extends MongoModels {}
_collection
property has been renamed to collection
. Ex: Customer._collection = 'customers';
will now be Customer.collection = 'customers';
.BaseModel.connect(options, callback)
arguments have changed to MongoModels.connect(uri, options, callback)
url
property is now uri
.I fail to connect mongodb.
when I register plugin,there is no error,but I got
curl: (7) Failed to connect to localhost port 8000: Connection refused
when I comment it,it's okay.
Instead of explicitly calling validate
inside the handler itself, do you approve of something like this to validate the payload to a Kitten
handler:
server.route({
method: 'POST',
path: '/kittens',
config: {
validate: {
payload: Kitten.schema
}
},
handler: function (request, reply) {
Kitten.create(request.payload, function (err, kitten) {
if (err) {
return reply(err);
}
reply(kitten);
});
}
});
I have a feeling I'm bringing up something very obvious and silly, but I haven't seen this pattern in the examples (yet). This may be a nice way to validate without repetition and returns useful error codes at the route level itself, if you won't be doing much else inside Kitten.validate()
.
mongo driver updated to 2.0.x. Is there a plan to update your dependencies ? Appreciate if you can do so earlier rather than later.
thx
I can find plugin example for hapi-mongo-models 6.x (via source history), but can't seems to find anything for 7, did you neglect this?
This looks like just the project I was looking for. Joi is awesome and it's great that you're using that.
Do you support pre and post hooks? I couldn't find any references to that in the docs. If not, is it anywhere on the roadmap?
According to jedireza/mongo-models#39, connection.db
is optional. I have observed that it is indeed optional and works as expected without db
when uri
contains the db name.
However, hapi-mongo-models still contains this line which throws an error if connection.db
is not provided:
Hoek.assert(options.mongodb.connection.db, 'options.mongodb.connection.db is required');
Which throws this error if db
is undefined or null:
Catch error on server start. Process will terminate now. { AssertionError [ERR_ASSERTION]: options.mongodb.connection.db is required
at new AssertionError (internal/assert.js:269:11)
I see that options.mongodb.connection
is just passed through to mongo-models which means that db should also be considered optional in hapi-mongo-models. Am I missing something? Can we just remove the above assertion in hapi-mongo-models?
Hi again
Just wanted to know where the callback is for this method
Line 42 in 436b617
Docs says it should take a callback but here isn't one here unless I am missing something?
Thanks
Simon
I'm opening this to gauge support for having hapi-mongo-models return Booms instead of the raw error objects from the native driver. I'd be happy to open a PR if this is something anyone else is interested in. Thoughts?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.