Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update $pull on Subcollection-Array doesn't work with collection2 #245

Closed
h2s20 opened this issue Jul 31, 2015 · 5 comments
Closed

Update $pull on Subcollection-Array doesn't work with collection2 #245

h2s20 opened this issue Jul 31, 2015 · 5 comments

Comments

@h2s20
Copy link

h2s20 commented Jul 31, 2015

I have a collection Member with an embedded array Fee as subcollection. One Member can have multiple Fees.
If I try to pull a Fee from the array the update function succeeds but nothing happens. The array doesn't get pulled from the array.
I think the problem lies with collection2 because if I use the update function from the mongo shell everythink works fine and if remove collectio2 it also works fine.

The reproduction can be found here on meteorpad: http://meteorpad.com/pad/uE7dmsXgianEB2Ea5/Pull-Subcollection-Array
If you comment out line 52 in common.js - it's possible to remove an object from the array
If you don't comment out line 52 in common.js - the callback of the update function is successfull but nothing happens.

//Members.attachSchema(Schemas.Members);
  • Am I using collection2 the wrong way or is this a bug?
  • Is there a possible workaround?

The schema:

Members = new Meteor.Collection('members');
var Schemas = {}
Schemas.Members = new SimpleSchema({ 
    fn: {
        type: String,
        label: "Firstname",
        max: 30
    },
    ln: {
        type: String,
        label: "Lastname",
        max: 30
    },
    fee: {
        type: Array,
        optional: true,
    },
        'fee.$': {
            type: Object
        },
        'fee.$._id': {
            type: String,
            autoValue: function(){
                return Random.id();
            },
            optional: false
        },
        'fee.$.amount': {
          type: String,
          label: "Amount",
          optional: true
        },
});
//Comment out the next line and the $pull of the subcollection will work
Members.attachSchema(Schemas.Members);

on the client:

Template.latestFee.helpers({    
    subCollection: function () {        
        f = Members.findOne({_id: "n6EzuD6tc5Ng66MKR"});
        //only return Subcollection
        return f.fee;
    },
});

Template.latestFee.events({
    'click button.remove-fee': function (evt) {
        evt.preventDefault();
        var subIndex = evt.currentTarget.getAttribute('data-index');
        Meteor.call("removeSub", "n6EzuD6tc5Ng66MKR", subIndex)
}})

method on the server

Meteor.methods({
    removeSub: function (memberID, subID) {
        console.log("MemberID: " + memberID + " | " + "SubID: " + subID);
        Members.update(
            {_id: memberID},
            {$pull:{fee: {_id: subID}}

            });
    }
});
@h2s20
Copy link
Author

h2s20 commented Aug 6, 2015

The following option-argument in the update function solves the problem: {getAutoValues: false}

Meteor.methods({
    removeSub: function (memberID, subID) {
        console.log("MemberID: " + memberID + " | " + "SubID: " + subID);
        Members.update(
            {_id: memberID},
            {$pull:{fee: {_id: subID}}}, {getAutoValues: false});
    }
});

It skips the generation of autovalues which is no problem in this case as I want to remove the objects but I think this might lead to a new problem if you want to modify the values of the subdocument.

@aldeed
Copy link
Collaborator

aldeed commented Aug 27, 2015

It's debatable whether it should be calling autoValue functions when the operator is $pull, but currently it does. So I think you could fix this by adding this as the first line of your autoValue:

if (this.operator === '$pull') return;

@TimFletcher
Copy link

When logging this.operator from inside my campaigns array autoValue I'm seeing $set rather than $pull for the following query:

Leads.update(
  { _id: leadId }},
  { $pull: {campaigns: { campaignId: campaignId }}},
  { multi: true }
);

Adding getAutoValues: false to the final options object does provide a workaround though. Thanks @h2s20!

@cdolek
Copy link

cdolek commented Jun 29, 2016

Thanks @h2s20 you saved me lots of time! "{ getAutoValues: false }" works.

@aldeed "if (this.operator === '$pull') return;" did not work. I am using aldeed:[email protected], aldeed:[email protected] | Many thanks for the great packages!

@diegodelfin7
Copy link

Thanks @h2s20 ! same issue.

kieckhafer added a commit to reactioncommerce/reaction that referenced this issue Aug 1, 2017
aaronjudd pushed a commit to reactioncommerce/reaction that referenced this issue Aug 2, 2017
* update cart schema with Product data

* add product data to cart update

* test fixes

* fixing tests

Suggested here: Meteor-Community-Packages/meteor-collection2#245

* lint fixes

* comment some code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants