These are chat archives for Automattic/mongoose

4th
Feb 2016
Daron Jones
@Wuntenn
Feb 04 2016 00:30
@alfredopacino you really need to read this: http://mongoosejs.com/docs/subdocs.html and http://mongoosejs.com/docs/populate.html. Your /api/community/posts may hang because you don’t call next(). change to If (err) next(err) console.log(arr); next();
Take a look at meanjs: https://github.com/meanjs/mean/blob/master/modules/articles/server/controllers/articles.server.controller.js. If you did something like this then for your posts then you could also do: posts = require(‘posts’); It will make your code read a lot clearer. Your route would become: app.route('/api/community/posts’).get(post.list).post(post.create); etc
Daron Jones
@Wuntenn
Feb 04 2016 00:40
(for some reason the css has broken on the last link (must have been in the last 48 hours cos it look fine when i last checked)
antonioaltamura
@antonioaltamura
Feb 04 2016 10:31

@Wuntenn very thanks but I'm not sure you get the problem, the problem is the some callbacks is fired too soon, so my

async.forEachOf(req.body.postedBy)

ends 'asynchronously' too soon and my "arr" is empty..

Konstantin Baierer
@kba
Feb 04 2016 11:39
@alfredopacino Your findOrAdd method requires a callback that is called when the async.series finishes
When you say findOrAdd(user) will not return anything useful.

Also:

    async.forEachOf(req.body.postedBy, function (user, key, callback) {
        arr.push(findOrAdd(user));
    }, function (err) {
        if (err) console.error(err.message);
        console.log(arr)
    });

you need to actually call callback, otherwise you break the flow of async.

antonioaltamura
@antonioaltamura
Feb 04 2016 12:16
In my idea is findOrAdd() returns an ObjectId (an old or an ObjectId just created)
(the cases in findOrAdd are only 2: an user is already present in user collection or I create the user)
Konstantin Baierer
@kba
Feb 04 2016 12:19
@alfredopacino You can't make async code synchronous. That's just how NodeJS works.
you need to use the callbacks: Pass functions around that take an error as the first argument.
antonioaltamura
@antonioaltamura
Feb 04 2016 12:22
could you edit my code or it's too complicated? I'm loose my mind with this problem..
Konstantin Baierer
@kba
Feb 04 2016 12:22
async.series wraps the two functions you specify but the call itself is asynchronous. You need to pass a callback to findOrAdd and call that in where you're now just doing return user._id
antonioaltamura
@antonioaltamura
Feb 04 2016 12:29
I'm sorry could you explain me in more details, obiouvsly I don't get completely this callback logic..
Konstantin Baierer
@kba
Feb 04 2016 12:32
@alfredopacino This is nothing mongoose specific just how all NodeJS code works: You pass around callbacks. Refactor your code so that you're doing findOrAdd(user, function(err, newUser) { ...}) and not newUser = findOrAdd(user). Read tutorials and use github code search for examples (e.g. how to use the async module)
antonioaltamura
@antonioaltamura
Feb 04 2016 13:56
It looks it works this way:
but i'm not sure it's a good way
function findOrAdd(userToFind,callback){
    var newuser=null;
    var user=null;
    async.series([
            function(callback){

                com_user.findOne({_id: userToFind._id},
                    function(err,obj) {
                        if(obj) {
                            user=obj
                            callback(null, obj);
                        } else {
                            newuser=userToFind.label
                            callback(null);
                        }
                    });
            },
            function(callback){
                if(newuser){
                var com_user1 = new com_user({
                    name: newuser,
                    age: 20
                });
                com_user1.save(function (err, n) {
                    if (err)
                        console.log(err);
                    else {
                        user=n;
                        callback(null,n);
                    }
                });
                } else callback(null);
            }
        ],
        function(err, results){
            callback(null,user)
        });

}
app.post('/api/community/posts', function(req,res){
    var arr=[];
  async.forEachOf(req.body.postedBy, function (user, key, callback) {
      findOrAdd(user, function(err, author) {
          arr.push(author._id);
          //why callback here?
          callback();
      });
    }, function (err) {
        if (err) console.error(err.message);
        console.log(arr)
      var com_post1= new com_post({
          content:req.body.content,
          postedBy:arr,
      });
      com_post1.save(function(err){
          if(!err)
              res.json({"New post added! ":req.body.content});
          else {
              res.json({"Error adding post":'error'});
              error(err)
          }
      });
    });
});
Konstantin Baierer
@kba
Feb 04 2016 14:01
don't name all your callbacks callback that is very confusing and causes scope errors. Call them something meaningful.
You also don't need async.series for findOrAdd. Just chain call save in the callback to findOne if the user wasn't found.
As to // why callback here?: To let async know that one iteration of forEachOf is finished. pass on err so the whole thing fails if any loop task failed.
Konstantin Baierer
@kba
Feb 04 2016 14:07
Might be a good idea to ask on some other platform/forum, these are rather basic NodeJS questions, not mongoose specific
J
@jhyland87
Feb 04 2016 16:01
@vaucouleur
did you see the update on the stack overflow thread?
ill try it out
J
@jhyland87
Feb 04 2016 16:09
Hah, perfect!
works
Risto Stevcev
@Risto-Stevcev
Feb 04 2016 17:58
hi
J
@jhyland87
Feb 04 2016 18:52
hola
J
@jhyland87
Feb 04 2016 20:30
This message was deleted
Sebastien Vaucouleur
@vaucouleur
Feb 04 2016 22:23
@jhyland87 I saw it. You only want to deep populate the first element of the array ?
@jhyland87 This plugin might help as well https://github.com/buunguyen/mongoose-deep-populate