1

Description of the problem:

I have two collections videos and specs. videos collection has a key called spec which corresponds to a specs id. Both collections are not empty.

My Template Helper:

  Template.List.helpers({
    videos: function(){
      var vids = Videos.find({ online: false}).fetch();
      return vids.map(function(value){
        console.log("id: " + value.spec);
        console.log(Specs.find({ id: value.spec }).fetch());

        //Issue here
        value.specName = Specs.find({ id: value.spec }).fetch()[0].name;
        return value;
      });
    }
  });

As you can see in my template helper I loop through the video array and add specName to the array.

The main problem comes from this specific line:

value.specName = Specs.find({ id: value.spec }).fetch()[0].name;

and more specifically this line: Specs.find({ id: value.spec }).fetch() which will return null every time.

What I've tried:

Naturally, my first thought would be to check what value.spec returns. And it returns an int between 1 and 15 (included) which is right. If value.spec is right, then how come the find() doesn't return anything?

I then decided to hard set it and tried this:

Specs.find({ id: 2}).fetch()

And this worked. Which is weird because on multiple occasions value.spec returns 2...

I've also tried intParse(value.spec) just in case, however that didn't work either.

Question

Why does Specs.find({ id: value.spec }).fetch() return null knowing that value.spec is set correctly and that a hard coded number works?

Requested json data: (from meteor mongo)

specs:

{ "_id" : "XKXHtQuiFsAew3dDy", "id" : 1, "name" : "Endocrine surgery" }
{ "_id" : "68jFidAMXTXpQtQye", "id" : 2, "name" : "General and digestive" }
{ "_id" : "GZSXToRXMfJgnH3CY", "id" : 3, "name" : "Pediatric surgery" }
{ "_id" : "T2mBz2gsXEqQaybmq", "id" : 4, "name" : "Thoracic surgery" }
{ "_id" : "hnuQzZiPKvYYDZhc8", "id" : 5, "name" : "Equipment" }
{ "_id" : "byE3A6HchvfhKdmR8", "id" : 6, "name" : "Gynecology" }
{ "_id" : "u5rrPB7asGW3NC6B2", "id" : 7, "name" : "Urology" }
{ "_id" : "umxKvR66oEx5dRppf", "id" : 8, "name" : "Cardiovascular surgery" }
{ "_id" : "bPcBTZn3t5ubRRcrQ", "id" : 9, "name" : "Endoscopic surgery" }
{ "_id" : "yNyAqQPoreNtdRZ34", "id" : 10, "name" : "NOTES" }
{ "_id" : "KG794eakRaztEqehG", "id" : 11, "name" : "Robotic surgery" }
{ "_id" : "QBrtvTg4GT7Tf7cAJ", "id" : 12, "name" : "Skull base surgery" }
{ "_id" : "HEhq6oBjuuMnrxE5a", "id" : 13, "name" : "Arthroscopy and upper limb surgery" }
{ "_id" : "xwpgHqZpBQP7WAnd5", "id" : 14, "name" : "Single port surgery" }
{ "_id" : "K4BgFupwNdDGD3449", "id" : 15, "name" : "Telemicrosurgery" }

videos:

{ "_id" : "L5Qi7YRRhn6Sfcjk8", "id" : "vd01en1065e", "title" : "Right inguinal hernia: open plug technique", "authors" : [ "E Pelissier" ], "date_published" : "2004-09-27", "abstract" : "", "tags" : [ "" ], "spec" : 2, "private" : true, "online" : false }
{ "_id" : "M8cuLW6KNCqKeP9vF", "id" : "vd01en1074e", "title" : "Laparoscopic splenectomy, posterior approach", "authors" : [ "D Mutter", " F Rubino" ], "date_published" : "2004-09-27", "abstract" : "", "tags" : [ "" ], "spec" : 2, "private" : true, "online" : false }
{ "_id" : "Ptzrxw8GifeMvQk9k", "id" : "vd01en1090e", "title" : "Intussusception of the intestine in the newborn", "authors" : [ "F Becmeur", " D Christmann", " I Kauffmann" ], "date_published" : "2004-09-27", "abstract" : "", "tags" : [ "" ], "spec" : 3, "private" : true, "online" : false }
{ "_id" : "oHWcX3vCBHuZQM9hR", "id" : "vd01en1103e_2", "title" : "Appendicular peritonitis: laparoscopic conversion", "authors" : [ "B Navez" ], "date_published" : "2001-11-05", "abstract" : "", "tags" : [ "" ], "spec" : 2, "private" : true, "online" : false }
{ "_id" : "6uzmxYxhd5DDuS2gG", "id" : "vd01en1108e", "title" : "Diaphragmatic hernias", "authors" : [ "F Becmeur" ], "date_published" : "2001-11-28", "abstract" : "", "tags" : [ "" ], "spec" : 3, "private" : true, "online" : false }
{ "_id" : "yHqruiQYeeQ9SDHpH", "id" : "vd01en1112e", "title" : "Laparoscopic excision of the cystic stump", "authors" : [ "J Leroy" ], "date_published" : "2004-09-27", "abstract" : "", "tags" : [ "" ], "spec" : 2, "private" : true, "online" : false}
{ "_id" : "fmjtk5WAEKitMxyGj", "id" : "vd01en1114e", "title" : "Laparoscopic gastric banding in a patient with a BMI of 40", "authors" : [ "JM Zimmermann", " D Fölscher" ], "date_published" : "2004-09-27", "abstract" : "", "tags" : [ "" ], "spec" : 2, "private" : true, "online" : false}

I've been stuck on this problem for a couple hours, I didn't want to post this on SO since I do believe it's a simple problem. However, it is mind boggling.

kemicofa ghost
  • 16,349
  • 8
  • 82
  • 131

2 Answers2

1

The problem here is the publication/subscription issue. You did not mention it, how do you handle publications and subscriptions but that is most likely the issue. What is happening is that when you browse your videos collection, which subscription is ready (since you hae any data in it) here: Videos.find({ online: false}) that not necessarly means that (in that precise moment) subscription handling Spec collection is ready as well. So even if on the server the query is working, on the client it's null, because the data are not synced between client and server YET. so you have to wait until both subscriptions are ready somehow. You can use template subscriptions, or waitOn function in your router.

Adam Wolski
  • 5,448
  • 2
  • 27
  • 46
0

First of all check on server side that your publication and subscription is ready and returning you back data check this like as

 Meteor.publish('Videso', function () {

  var result= Videso.find({});
  console.log(result);
   return result
   });

if console.log returning you records on server side i have a solution then your problem

the solution of your problem is that

   Template.List.helpers({
   videos: function(){

    var vids = Videos.find({ online: false}).map(function (value) {
             console.log("id: " + value.spec);
             var idValue  = Specs.findOne({ "id": value.spec })
             console.log("idValue===",idValue)
             return _.extend(value, idValue);
       });
           console.log(vids);      //here merged data of both table having 
                                  // relvent record will returned
           return vids;



       }


  });

Just implement it and check data on your template it will be ready for you and vote me then :)

Mudassir
  • 13
  • 3