arraysmongodbmeteormeteor-autoformmeteor-collection-hooks

Meteor Autoform, collection hooks - How to insert into user profile array after a collection insert?


I'm trying to insert into a user profile array after an autoform inserts into another collection (Meteor.users).

My simple schema array is set up like this - (within the profile schema)

listings: {
type: [String],
optional: true
},
"listings.$.id": {
type: String,
optional: true
}

And this is my collection-hook method that should be inserting after listing insert.

//Add listing to user collection on submit
Listings.after.insert(function(userId, doc) {
console.log("STUFF");
Meteor.users.update({_id : userId},
{
    $push :
    {
        'profile.listings.$.id' : this._id 
    }
}

In my eyes, this should work. The form inserts properly without the collection-hook, but now when I submit the form I get this error in my JS console:

Error: After filtering out keys not in the schema, your modifier is now empty(…)

The console.log("stuff") triggers, I see that in the console before the error.

Anybody have any ideas on how to do this?

EDIT - fixed a few things by switching it to :

Listings.after.insert(function(userId, doc) {
console.log("STUFF" + userId + '     ' + this._id);
Meteor.users.update({_id: userId },
{
    $set :
    {
        "profile.listings.$.id" : this._id 
    }
}

) });

Now I can't insert into the array because of the $ operator.


Solution

  • Assuming listings is just an array of objects with the id field, you could do:

    listings: {
      type: [Object],
      optional: true
    },
    "listings.$.id": {
      type: String,
      optional: true
    }
    
    Listings.after.insert(function(userId, doc) {
      var id = this._id;
      Meteor.users.update({_id: userId }, {
        $push : {
            "profile.listings" : { id: id }
        }
      }); 
    });
    

    This changes your listings from an array of Strings to an array of objects - you can't have a property of id on a String. This then allows you to do $push on the profile.listings array with the object in question. If you're literally just storing an ID on listings though, you could simplify this further:

    listings: {
      type: [String],
      optional: true
    }
    
    Listings.after.insert(function(userId, doc) {
      var id = this._id;
      Meteor.users.update({_id: userId }, {
        $push : {
            "profile.listings" : id
        }
      }); 
    });
    

    Maybe you're leaving some code out, but with your current schema you don't need anything but an array of strings - no need for an id property.