Meteor error - MongoDB: Can't apply $ addToSet modifier on non-array

I am following the recently published book " Getting Started with Meteor.js JavaScript Framework " by Isaac Strack. The book works with Meteor 0.5.0. I am working with version 0.5.4.

In the book, you create a multi-category application into which you insert data to track household items and to whom it can be shared. I deployed the app to meteor subdomain and it works fine. It does not replicate my local MongoDB error.

LendLib

I'm in chapter 5 and I just removed autopublish from the app and specified my local data feeds.

Locally, just under the Tools category, when I try to add a new item to the category, I get this error in the browser console:

Exception while simulating the effect of invoking '/Lists/update' Error {} Error: Cannot apply $addToSet modifier to non-array
    at Error (<anonymous>)
    at LocalCollection._modifiers.$addToSet (http://localhost:3000/packages/minimongo/modify.js?e7f02f0df0bff9f0b97236f9548637b7ede1ac74:178:13)
    at Function.LocalCollection._modify (http://localhost:3000/packages/minimongo/modify.js?e7f02f0df0bff9f0b97236f9548637b7ede1ac74:53:9)
    at LocalCollection._modifyAndNotify (http://localhost:3000/packages/minimongo/minimongo.js?7f5131f0f3d86c8269a6e6db0e2467e28eff6422:474:19)
    at LocalCollection.update (http://localhost:3000/packages/minimongo/minimongo.js?7f5131f0f3d86c8269a6e6db0e2467e28eff6422:444:12)
    at m.(anonymous function) (http://localhost:3000/packages/mongo-livedata/collection.js?3ef9efcb8726ddf54f58384b2d8f226aaec8fd53:415:36)
    at http://localhost:3000/packages/livedata/livedata_connection.js?367884963b120d457819216ff713b2586b266dde:540:25
    at _.extend.withValue (http://localhost:3000/packages/meteor/dynamics_browser.js?46b8d1f1158040fcc2beb7906ec2f932871a398d:21:19)
    at _.extend.apply (http://localhost:3000/packages/livedata/livedata_connection.js?367884963b120d457819216ff713b2586b266dde:539:47)
    at Meteor.Collection.(anonymous function) [as update] (http://localhost:3000/packages/mongo-livedata/collection.js?3ef9efcb8726ddf54f58384b2d8f226aaec8fd53:266:23) logging.js:30
update failed: Internal server error logging.js:30

      

There is already one item in the tool category that was introduced earlier in the tutorial. If I type into the console lists.findOne({Category:"Tools"});

, I get output that recognizes the item in the object:

Object
  Category: "Tools"
  _id: "eaa681e1-83f2-49f2-a42b-c6d84e526270"
    items: Object
      LentTo: "Steve"
      Name: "Linear Compression Wrench"
      Owner: "me"
      __proto__: Object
  __proto__: Object

      

However, the screen output is empty:

enter image description here

Naturally I tried restarting the meteorite server and shutting down the browser, but without permission. I'm new to MongoDB, so it's not clear where to go to understand what is causing this problem, or why.

You can see the application here . You can view the code on GitHub .

+3


source to share


2 answers


function addItem(list_id, item_name) {
    if(!item_name && !list_id)
      return;
    lists.update({_id:list_id}, {$addToSet:{items:{Name:item_name}}});
  }

      

It looks like you are trying to add an object to the set. You get an error while simulating. Let's try to investigate this error. Code that contains errors:

https://github.com/meteor/meteor/blob/master/packages/minimongo/modify.js

 $addToSet: function (target, field, arg) {
    var x = target[field];
    if (x === undefined)
      target[field] = [arg];
    else if (!(x instanceof Array))
      throw Error("Cannot apply $addToSet modifier to non-array");
    else { ...

      

Oh uh, throw Error("Cannot apply $addToSet modifier to non-array.")

.

Look at your code:

Object
  Category: "Tools"
  _id: "eaa681e1-83f2-49f2-a42b-c6d84e526270"
...
  items: Object
...

      

items

is an object, not an array! It will fail.

Can you $addToSet

facility with Mongo? Take a look at the code.



https://github.com/mongodb/mongo/blob/4a4f9b1d6dc79d1ba4a7d7eaa9e4eb6d00aa466c/db/update.cpp

 case ADDTOSET: {
            uassert( 12592 ,  "$addToSet can only be applied to an array" , in.type() == Array );
            ...
        }

      

Nope! This is from the old mongo code because the modern codebase is stretching, but the same thing.

I only found one insert

in your code.

'keyup #add-category': function(e, t) {
  if (e.which === 13) {
    var catVal = String(e.target.value || "");
    if (catVal) {
      lists.insert({Category:catVal});
      Session.set('adding_category', false);
    }
  }
},

      

Try it lists.insert({Category:catVal,items:[]})

. So the elements are initialized as an array and not an object when it was first used.

Also, I don't think I'm $addToSet

comparing the objects in the array the way you would like, so consider creating a separate collection items

containing categoryId

.

It's just a coincidence that it works in one place and not another.

+11


source


I had the same problem following the same tutorial. When using inserts directly from the manual (Tools and DVDs) minimongo inserts elements as objects instead of arrays. I don't know if it was just a bug or if the code base changed, in any case I changed:

lists.insert({Category:"DVDs", items: {Name:"Mission Impossible", Owner:"me", LentTo:"Alice"}});

      

to



lists.insert({Category:"DVDs", items: [{Name:"Mission Impossible", Owner:"me",LentTo:"Alice"}]});

      

just put the elements in [] to force it to the array, and similarly applied tool insertion. Works great.

+2


source







All Articles