These are chat archives for Automattic/mongoose

12th
Apr 2016
Kevin Whitman
@keverw
Apr 12 2016 03:16
I’m still learning MongoDB and Mongoose. When I call mongoose.model, it creates the collection even if no insert or update it seems. Is this being sync, blocking then? Was trying to find the code doing that but had trouble following the code of the actual Mongoose code.
Vlado Tesanovic
@vladotesanovic
Apr 12 2016 07:53
@keverw Why is that important? if it create?
Kevin Whitman
@keverw
Apr 12 2016 07:54
@vladotesanovic Just kinda curious since there's no callback when loading in the model. If it's doing blocking IO checking for the collection and creating it
Vlado Tesanovic
@vladotesanovic
Apr 12 2016 09:48
@keverw that is pretty much Mongo stuff, it creates databases and collections on the fly, when you try to use it
Kevin Whitman
@keverw
Apr 12 2016 09:49
@vladotesanovic interesting. Just don't know if that would slow down my app to load in a model and not use it yet... I figured i'd require it on pages where I only needed. But thinking maybe best to just load them all at app startup and reference them later
Vlado Tesanovic
@vladotesanovic
Apr 12 2016 11:12
@keverw you should not think of that, Mongo is very flexible database
Kevin Whitman
@keverw
Apr 12 2016 11:14
@vladotesanovic Hmm I was thinking of Node blocking, not Mongo since no callback on it looks but hmm maybe it's not that bad.
Vlado Tesanovic
@vladotesanovic
Apr 12 2016 11:14
@keverw You think that creation of collection will block your application?
Kevin Whitman
@keverw
Apr 12 2016 11:15
@vladotesanovic When you use the model function, it creates it even without inserting, finding, updating it seems. So if there's no Callback when it does that, in theory it's blocking the IO while it talks to Mongo? hmm idk maybe not...
I think I am probably thinking too much into things hah
Vlado Tesanovic
@vladotesanovic
Apr 12 2016 11:16
@keverw you are going too much, and there is no callback for that... And it will never - ever make you any problem
Kevin Whitman
@keverw
Apr 12 2016 11:18
@vladotesanovic Thanks. I do tend to overthink things haha.
Vlado Tesanovic
@vladotesanovic
Apr 12 2016 11:18
@keverw focus on your business logic :+1:
Kevin Whitman
@keverw
Apr 12 2016 11:19
@vladotesanovic Yeah agreed :)
Diego Aguilar Aguilar
@diegoaguilar
Apr 12 2016 16:14
I have following code where I basically create a doc and update another (based on created doc's _id), it's working and it actually properly creats the new doc and the update gets done as expected, however I'm getting undefined as the result for the doc update
module.exports.createOwnerUser = (req, res) => {
  let reqUser = req.body.user;
  let user = new User({
    account: req.session.account._id,
    name: reqUser.name,
    lastnames: reqUser.lastnames,
    completeName: `${reqUser.name} ${reqUser.lastnames}`,
    address: reqUser.address,
    telephones: [{number: reqUser.mobile, type: 'mobile'}],
    type: 'owner'
  });
  let userCreation = user.saveAsync();
  let accountUpdate = Account.updateAsync(
    {_id: req.session.account._id},
    {$set: {user: user._id}});
  bluebird.join(userCreation, accountUpdate)
    .then((createdUser, updatedAccount) => {
      console.log(updatedAccount);
      let a = Object.assign({}, updatedAccount, {password: null});
      return res.status(201).json({user: createdUser[0], account: a});
    })
    .catch(err => {
      return res.status(500).json({error: err});
    });
};
both models are defined after mongoose is set up with bluebird:
const bluebird = require('bluebird');
const mongoose = bluebird.promisifyAll(require('mongoose'));
the issue is that console.log(updatedAccount); logs undefined ... is there something else I should do to get the proper result there?
LeonineKing1199
@LeonineKing1199
Apr 12 2016 16:54
Promises only resolve to one value
Not two

.then((createdUser, updatedAccount) => {

The problem with this line is that the Promise above it will only resolve to one value, not two so of course updatedAccount is undefined as it's never passed in

If you want more variables to be passed through the chain, you need to resolve the promise with either an array of values or an object of values
You could also just use the co() library which makes async flow much easier to reason about than dense promise chains
paulgrove
@paulgrove
Apr 12 2016 17:02
@diegoaguilar your using Promise.join wrong
bluebird.join(userCreation, accountUpdate, (createdUser, updatedAccount) => {
    // ...
})
.catch(err => {
    // ...
});
bluebird.join returns a promise, but that promise doesn't provide the seperated arguments, you must use the callback provided to join for that
LeonineKing1199
@LeonineKing1199
Apr 12 2016 17:06
Oh, does Bluebird support super cool stuff like that?
paulgrove
@paulgrove
Apr 12 2016 17:06
@LeonineKing1199 yeah loads of useful Promise stuff in bluebird
map, each, race, filter, reduce etc etc
its just utility functions though, not an extension to Promises themselves
@diegoaguilar Promise.all is like join, but returns all the promise results in an array
(as an alternative)
LeonineKing1199
@LeonineKing1199
Apr 12 2016 17:09
That's super cool
I've been crushing on co() lately
paulgrove
@paulgrove
Apr 12 2016 17:11
yeah I remember seeing co, but never used
I havn't really got my head around using generators yet either
LeonineKing1199
@LeonineKing1199
Apr 12 2016 17:19
It's kind of a misnomer. Basically, a generator is an isolated context and the iterator is how you get values out and push values into the generator's context.
So for co, the generator spits out a Promise
co takes this promise and on resolve, it forwards the resolved value back into the generator
so that's why this will work when using co:
var databaseResult = yield asyncDatabaseCallThatIsAPromise;
We yield out a Promise and on resolve, it calls it.next(valueOfPromise)
Which is how you pass values into the generator
paulgrove
@paulgrove
Apr 12 2016 17:22
We're stuck (for a little while) on quite an old version of node, but I'm on holiday so I'll have a play with it
LeonineKing1199
@LeonineKing1199
Apr 12 2016 17:24
co() handles conditional logic and shared state among async calls incredibly well. It's kind of freaky how synchronous your code will wind up looking.
paulgrove
@paulgrove
Apr 12 2016 17:26
yeah, it looks nice, I see now a bit better looking at some co examples
its a shame I can't really use it in the project I am working on most
I could change all the service code to call node with --harmony
but I'm not too keen on that right now
Pier-Luc Gagnon
@Nepoxx
Apr 12 2016 17:57
How's debugging with co?
Also, did they improve the performance? Last I checked it was being outperformed by, well, pretty much everything else
LeonineKing1199
@LeonineKing1199
Apr 12 2016 17:59
Eh, it's JS. Performance went out the window with language choice XD
That being said, I haven't noticed any real slowdown
LeonineKing1199
@LeonineKing1199
Apr 12 2016 20:03
As for debugging, it's as simple as try-catch is
Pier-Luc Gagnon
@Nepoxx
Apr 12 2016 20:36
JS on v8 is amazingly fast, I don't buy that.
I thought debugging would be more complex with co since it adds a few layers of complexity to your code
Bluebird/Promises are not all that great to debug either
LeonineKing1199
@LeonineKing1199
Apr 12 2016 20:58
Nah, debugging is relatively "normal", i.e. it uses normal JS semantics
paulgrove
@paulgrove
Apr 12 2016 21:17
What's the best way to add extra information/meta data to the schema?
that is I want to add information about the Schema it self, not statics about the data
I could use statics I think, Its just that it seems to be for a different use