简体   繁体   中英

Meteor update collection error

I have no idea whats wrong with my code, im reading the book Discover Meteor and building a small app to learn those concepts better:

Template.panelCM.events({
'click .editProductsCol': function(e) {
    e.preventDefault();
    if (confirm('Edit?')){

    var currentProduct = this._id;

    var productOptions = {
        name: $(e.target).find('[name=productName]').val(),
        description: $(e.target).find('[name=productDescription]').val()
    };

    Products.update(currentProduct, {$set: productOptions}, function(error) {
        if (error) {
            alert(error.reason);
            throwError('Error');
        } else {
            Router.go('tabPage');
        }
    });
}},

'click .deleteProductsCol': function(e) {
    e.preventDefault();

    if (confirm("Delete?")) {
        var currentProduct = this._id;
        Products.remove(currentProduct);
        Router.go('tabPage');
    }
}});

The delete part works well, its just the update that I don't figure out whats wrong.. It gives me this error after submitting: MongoError: '$set' is empty. You must specify a field like so: {$mod: {<field>: ...}} MongoError: '$set' is empty. You must specify a field like so: {$mod: {<field>: ...}}

This is my template:

<template name="panelCM">
{{#each products}}
    <div class="col-xs-12 col-sm-6 col-md-6 mainCol">
        <img src="../{{image}}"/>
        <input type="text" name="productName" id="productName" class="form-control" placeholder="{{name}}">
        <textarea name='productDescription' id="productDescription" class="form-control colP" rows="10"
                  placeholder="{{description}}" style="color: black"></textarea>
        <button type="submit" class="btn btn-lg btn-success form-control editProductsCol">Edit</button>
        <button type="submit" class="btn btn-lg btn-danger form-control deleteProductsCol">Delete</button>
    </div>
{{/each}}</template>

What am I doing wrong, I didn't quite understand that productOptions var I think, if I understood correctly im just creating an object that gets whatever I put on that html element and then I pass it to my Products db to update it, what I don't quite understand is if I need to use an id on my template aswell, I saw it on the Discover Meteor book, but it doesn't make sense since im finding the correct element with the 'name' thing (no idea what thats called).. Also the name and description Im using in the productOptions, should be the same as the one im using on my db right?

$.find looks to the descendants of the DOM element it's called on. You're calling it on the edit button, which has no children. That means it finds nothing, and the call to .val() returns undefined . MongoDB's complaining that you're setting both fields to undefined , which means pretty much nothing. Try something like this instead:

'click .editProductsCol': function(e, template) {
    e.preventDefault();
    if (confirm('Edit?')) {

    var productOptions = {
        name: template.$('[name=productName]').val(),
        description: template.$('[name=productDescription]').val()
    };

    Products.update(this._id, {$set: productOptions}, function(error) {
        if (error) {
            alert(error.reason);
            throwError('Error');
        } else {
            Router.go('tabPage');
        }
    });
  }
},

A Meteor primer

Let's go through the code. Meteor binds this inside an event handler to your model, so this._id (that you assigned to the currentProduct variable) gets the id of the document you want to update.

So, now you now what document (MongoDB items are called documents ) to update. How to do it and what to set it to? Well, we want to update based on the form data. The second parameter passed to the event handlers is the template instance, which contains a $ property that queries the DOM only inside the template's context. That's where we get our form values.

Now, we just have to call the update method on the Meteor.collection and we're gold. As you can see from the docs, it takes the _id as a selector, a modifier object and a callback. Your modifier is the object with the $set property. It tells MongoDB to keep the document as it is, just adding/replacing the fields we're indicating (instead of replacing the whole document).

One more thing, if there's no specific reason to do otherwise, I suggest you replace the placeholder attribute on your input elements with value s. The placeholder is just a visual cue, it means nothing to the form content itself.

    <input type="text" name="productName" id="productName" class="form-control" value="{{name}}" placeholder="Enter the name">
    <textarea name='productDescription' id="productDescription" class="form-control colP" rows="10" value="{{description}}" style="color: black" placeholder="Enter a description"></textarea>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM