jseiller
jseiller

Reputation: 232

MeteorJS : Template rendered & Meteor method call

This question follows my previous one : Meteor: How to publish custom JSON data

I created a Meteor method building a complex JSON (built with different collections etc.). With those datas I need to build a chart using D3.js.

I used to set the data in the Session but as I realized they need to be refreshed each time I am reaching the page, it does not work properly.

Obviously there is something I did not understand in the mechanics, but here is my code :

Template.myPage.rendered = function(){

    var data = Meteor.call('myData');

    var svgContainer = d3.select("#svg");

    var margin = 40;
    var width = parseInt(d3.select("#svg").style('width'),10);
    var height = parseInt(d3.select("#svg").style('height'),10);
    // ... some more D3 code where I need the data

The error I'm getting is :

"Exception from Tracker afterFlush function: data is undefined

I have already tried to call the Meteor Method outside the Template and put the result in the Session (in the callback function), but it did not work. I've also tried to use reactive var, but I couldn't make it.

Thanks a lot.

Upvotes: 0

Views: 1139

Answers (4)

user3413838
user3413838

Reputation: 320

you can use "meteor-reactive-method". Here's an inline link to https://github.com/stubailo/meteor-reactive-method

then in client

 Template.myPage.rendered = functiopn(){
   Tracker.autorun(function(){
     var data = ReactiveMethod.call('myData');
      if(data === undefined){
       //this is the long way
       console.log("Wait the data value still undefined")
      }else{
       //load all the D3 stuff
       console.log(data)
      }
   });
 }

in server

 Meteor.methods({
  myData: function() {
    return CollectionName.find().fetch()
 }
})

Upvotes: 0

jseiller
jseiller

Reputation: 232

Thanks to twitter and @callmephilip I found the answer (and I am ashamed I couldn't find it myself ! :D)

The only thing to do is to put all the d3 code inside the method callback :

Template.myPage.rendered = function(){
    Meteor.call('myData', function(err, result){
        if(err){
           console.log(err);
        }else{
             // all the D3.js code 
        }
    });
};

Have a good day ;)

Upvotes: 1

Philip Nuzhnyy
Philip Nuzhnyy

Reputation: 4740

I would try smth like this:

Template.myPage.rendered = function(){
    Meteor.call('myData', function(error,data){
       // if !error, data should be good
       var svgContainer = d3.select("#svg");

       var margin = 40;
       var width = parseInt(d3.select("#svg").style('width'),10);
       var height = parseInt(d3.select("#svg").style('height'),10);
    });
};

Upvotes: 1

Ethaan
Ethaan

Reputation: 11376

Well, you get the "undefined" error when you are trying to use a variable without a value.

console.log(data) //return undefined

Based on what you say, the Meteor.method returns a JSON who depends on other collections.

So I think the best option you have here is to use a waitOn on the myPage Template.

waitOn:function(){
 //return all the collection that the JSON depends
}

You can try with the session, and using a Tracker too.

var data = Meteor.call('myData');
Session.set('data',data)

//and later

     Template.myPage.rendered = functiopn(){
       Tracker.autorun(function(){
         var data = Session.get('data')
          if(data === undefined){
           //this is the long way
           console.log("Wait the data value still undefined")
          }else{
           //load all the D3 stuff
           console.log(data)
          }
       });
     }

GL

Upvotes: 1

Related Questions