Nyxynyx
Nyxynyx

Reputation: 63599

Meteor.js Collection empty on Client

Why is it that myCollection.find().fetch() returns an empty array [] even though the call is made within if(data){...}? Doesn't the if statement ensure that the collection has been retrieved before executing the console.log()?

Template.chart.rendered = function() {

        var data = myCollection.find().fetch();

        if(data) {
            console.log(data);
        }

        $('#chart').render();

}

This returns [] in the browser Javascript console.

Upvotes: 5

Views: 8261

Answers (4)

MistereeDevlord
MistereeDevlord

Reputation: 884

It seems when you "remove autopublish" you have to also subscribe on the client.

  if(Meteor.isClient) {
    Meteor.startup(function() {
      Myvars = new Mongo.Collection("myvars");
      Meteor.subscribe('myvars')
    });
  }

and enable allow and publish on the server

  if(Meteor.isServer) {
    Meteor.startup(function () {
      Myvars = new Mongo.Collection("myvars");
      Myvars.allow({
        insert: function () {
          return true;
        },
        update: function () {
          return true;
        },
        remove: function () {
          return true;
        }
      });
      if (Myvars.find().count() == 0) {
        Myvars.insert({myvalue:'annoyed'});
      }

      Meteor.publish("myvars", function() {
        return Myvars.find();
      });
    });
  }

I'm new to this as well. I was just looking to have a global value that all clients could share. Seems like a useful idea (from a beginner's perspective) and a complete oversight on the Meteor teams behalf, it was nowhere clearly documented in this way. I also still have no idea what allow fetch is, that too is completely unclear in the official documentation.

Upvotes: 2

Łukasz Jagodziński
Łukasz Jagodziński

Reputation: 3079

The problem is that you have to wait for data from the server. When you just use Template.name.rendered function it is immediately invoked. You have to use Template.name.helpers function to wait for data from the server. Everything is described in the documentation.

Upvotes: 2

Tarang
Tarang

Reputation: 75945

You could use count() instead which returns the number of results. data itself would be an empty array, [] which isn't falsey ( [] == true ).

Also don't use fetch() unless you're going to use the raw data for it because its quite taxing. You can loop through it with .forEach if you need to.

var data = myCollection.find();

if(data.count())
  console.log(data);

//If you need it for something/Not sure if this is right but just an example
$('#chart').render(data.fetch())

Upvotes: 6

Salvador Dali
Salvador Dali

Reputation: 222461

It does, but in javascript you have the following strange behaviour

if ([]){
  console.log('Oops it goes inside the if')
} // and it will output this, nontheless it is counter-intuitive

This happens because JS engine casts Boolean([]) to true. You can how different types are casted to Boolean here.

Check if your array is not empty in the beginning.

a = [];
if (a.length){
  //do your thing
}

Upvotes: 1

Related Questions