'$set' is empty. You must specify a field like so: {$set: {<field>: ...}}

Hi to all!

I have a problem: there are 20 photos in my mongo collection. 3 or more don’t have a rating, and if I try to click on the place, where stars must be, console shows this kind of mistake:
update failed: MongoError: ‘$set’ is empty. You must specify a field like so: {$set: {: …}}
I can’t understand, what is wrong, just because of all others photo have their rating. Important: every time, when I reset meteor, stars disappear from different photos. Help me please to fix it!
The code is:
“click .js-rate-image”:function(event){
var rating =$(event.currentTarget).data(“userrating”);
console.log(rating);
var image_id = this.id;
console.log(image_id);
Images.update({_id: image_id},
{$set: {rating:rating}});

  }

I thing, that problem in barbatus:star rating.
Is there any idea?

Seems as if rating is undefined. Have you checked this via console.log(rating)?

Yes, you are absolutely right, waldgeist. All stars show on console somthing like this:

main.js:43 5
main.js:45 C9tcb5943FmjFXsxu

But several, which I can’t see in browser, show this:

main.js:43 undefined
main.js:45 7pwut3cMxpz53Cg8B
meteor.js?hash=e3f53db…:930 update failed: MongoError: ‘$set’ is empty. You must specify a field like so: {$set: {: …}}

And the question is: why do they show different results, while I use the same templates for both? And why, after every reset meteor there are problem with rating of different photos?
The irony is, that I’ve already specify a field as it have to be… Get stuck…

I can only guess what happens here, since you did not provide the whole JS code of your template. But I would say it is a race condition, i.e. the data from the database is not available yet when you try to initialize the stars. This could explain why only some stars are missing at random. This may happen if only the data of the other stars is available yet.

Template.images.events(
{
‘click .js-image’:function(event)
{
$(event.target).css(“width”, “100px”);
},
“click .js-del-image”: function(event)
{
var image_id = this._id;
console.log(image_id);
$("#"+image_id).hide(‘slow’, function()
{
Images.remove({"_id": image_id})
})

     },
  "click .js-rate-image":function(event){
     var rating =$(event.currentTarget).data("userrating");
     console.log(rating);
     var image_id = this.id;
     console.log(image_id);
     Images.update({_id:image_id},
           {$set: {rating:rating}});

  },
  'click .js-show-image-form':function(event){
     $("#image_add_form").modal('show');
  }

});
there is full code of this template, what do you think about it? And, if your guess is right, how can I fix it?
Thanks in advance.

Hm. Where’s the code that retrieves the star ratings from the database to display them?

This is the only code, that refers to stars rating. Or, may be you mean template from html file? Than here it is:

{{#if currentUser}}
add images
{{/if}}

{{#each images}}
<div class="col-xs-12 col-md-3" id="{{_id}}">

  <div class="thumbnail">

     <img class="js-image thumbnail-img" src="{{img_src}}" alt="{{img_alt}}"/>

    <div class="caption">

      <h3>Rating: {{rating}}</h3>

      <p>{{>starsRating mutable=true class="js-rate-image" id=_id}}</p>

      <p>{{img_alt}}</p>   

      <p>User: {{getUser createdBy}}</p>     

      <button class ="js-del-image btn btn-warning ">Delete</button>      

    </div>

  </div>

</div> 

{{/each}}

Ok, thanks. If I understood your problem correctly, you would like to display star ratings for images that have been already rated in the database, right? In this case, I am missing JavaScript code to actually retrieve these ratings from the database and hand them over to starsRating. The way you’ve implemented it looks to me as if the rating would always be undefined until the user manually sets a rating, since you are not using the rating attribute of {{> starsRating }}. So I would consider it quite natural that the rating is undefined.

Another hint: You are defining an event handler that reacts on click events on .js-rate-image to retrieve the star value and store it into the database. If you do it this way, it could happen that your event handler is fired before star rating’s own event is being fired. So you would not be able to read out the correct value. To retrieve the value once it has been changed in a reliable way, the stars-rating package defines its own event that you can hook to:

$('#rating').on('change', ...)

This would assure your event handler is called once the star rating has been updated.

You should place this code inside a Template.images.onRendered(), like this:

Template.images.onRendered(function() {
  $('.js-rate-image').on('change', function(event) {
     ... code of your existing event handler ...
  });
});

Note: For some external libraries it is sometimes necessary that you wrap the jQuery call into an additional Meteor.defer() block to ensure the DOM has already been rendered when hooking the event handler to the DOM nodes.

You’re talking about the second problem, which also needs to be solved. Rating doesn’t save after reload (only as a number, but not as a numder of stars, like this:


As you can see, photos have thair rating, but stars don’t show it.
But I would like to solve first another problem:
Some photos even doesn’t have their own stars for rating, and if I click on that place, where the stars should be, console.log shows
main.js:43 undefined
main.js:45 7pwut3cMxpz53Cg8B
meteor.js?hash=e3f53db…:930 update failed: MongoError: ‘$set’ is empty. You must specify a field like so: {$set: {: …}}

Is it possible you are rendering tags with the same id value? Multiple identical ids on the same page are known to cause rendering issues in Blaze. You declare:

<div class="col-xs-12 col-md-3" id="{{_id}}">

and later pass the same _id to your starsRating template. Do you also use _id to set an id in that template?

It’s hard to say what’s going wrong without seeing the whole picture.

To make things easier, I’d like to offer you to contact me via https://app.guzz.io. Guzz is a community that allows support via video-chat (it’s my own Meteor project btw). Just enter “Meteor.js” into the search and you will find me as Tom. We’re already six Meteorists on Guzz. :slight_smile:

Ok, Tom, I’ll try to do it tomorow, if it’s comfortable for you. Thank you for your willingness to help.

Rob, thanks, I’ll try to think in this dirrection.

No problem. Just contact me via Guzz and we’ll find a timeslot.

Hi, Rob! I’ve tryed to change the id by this way: id="rating{{_id}}. But, unfortunately, it doesn’t help me to solve problem with stars rating. And also I was surprised, that nothing was changed after correcting id.