0

The basic idea is to iterate through a folder, read all files inside, get their names and insert them to some html template as list of pages.

The iteration is no problem, but the inserting is harder for me.

My code (only basic logic):


Template (template.html)

<template name="myTemplate">
    <p>{{myHelper}}</p>
</template>

Script (main.js)

if (Meteor.isServer) {

    Meteor.methods({
        myMethod: function(){
            console.log("Hello");
            return "Hi";
        }
    })
}


if (Meteor.isClient) {

    Template.myTemplate.helpers({
        myHelper: function(){    
            Meteor.call("myMethod");    
        }
    })
}

From these actions I only get this output in the server console:

"Hello"

And my template contains an empty <p> tag - I expect this: <p>Hi</p>.

So my question is how to get the return value from myMethod in the template? If this gonna work, I would apply this logic to the iteration. Or, is there some better way how to do all of this?

Jiří Zmrhal
  • 143
  • 1
  • 2
  • 7

3 Answers3

1

As mentioned in a comment to ilrein's answer - the return value of Meteor.call(...) is always undefined because it is asynchronous. You need to set up a reactive variable in the onCreated callback for your template and call the Meteor method from there as well.

To add the ReactiveVar package: in the terminal run: meteor add reactivevar

In your code you need something like:

Template.myTemplate.onCreated(function() {
    var self = this;
    self.myMethodResult = new ReactiveVar('');
    Meteor.call('myMethod', {...some params...}, function (err, result) {
        if (err) {
            // handle the error
        } else {
            self.myMethodResult.set(result);
        }
    });
});

Template.myTemplate.helpers({
    myHelper: function () {
        return Template.instance().myMethodResult.get()
    }
});

Apologies if there's any typos in there, I did a quick translation from CoffeeScript so it may need some edits...

Michael Mason
  • 932
  • 5
  • 15
  • Actually this is much better. It doesn't make sense to do a Meteor call in a helper (I'm not sure its possible even, it may just return undefined as you stated). I think for the OP's case, a Session.set/get would be ideal, as he's obviously a beginner. – ilrein Jun 16 '15 at 14:42
0

There is much for you to learn.

  1. Meteor.call is a client side method, which means it must be in async format Meteor.call('method', args, function(error, result) {})
  2. Putting this in a helper doesn't really make sense, although it still works. Try calling your server method in either a click event or onRendered.

EDIT: If your goal with the helper is to output the text, you can try:

Template.myTemplate.helpers({
  myHelper: function(){    
    Meteor.call("myMethod", function(e, r){
      if (!e) {
        return r;
      }
    });    
  }
})
ilrein
  • 3,833
  • 4
  • 31
  • 48
0

Hopefully this provides a good example of how things work with Meteor Methods:

<template name="test">

    {{ myHelper "secret code" }}

</template>

/client/test.js

Template.test.helpers({

  myHelper: function(somethingToSay) {

    // Meteor.call needs the name of the method, the arguments, and then a callback function
    // with error as the first argument and the returned result as the second

    Meteor.call("myMethod", somethingToSay, function(error, result){
      if(error){
        // Do something
        console.log("This is the error from the Meteor.call: ", error);
      } else {
        // There's no error, so there should be a result
        // Since this is async and inside a callback, you cannot return the result.
        // You have to take the result and do something with it right inside here
        Session.set("myResult", result);
      }
    });

    return Session.get("myResult");

  }

});

/server/methods.js

Meteor.methods({

  myMethod: function(arg1) {
    // This is the FIRST thing you should have in a MM - check your inputs for type
    // Maybe also do some additional validations on the input to protect yourself from attack
    check(arg1, String)
    // feel free to do something with arg1, it's just here for demonstration
    // you will see this console log in the server console
    console.log(arg1);
    if(arg1 === "secret code"){
            return "Secret code checks out!";
        } else {
            return "Secret code does not check out."
        };
  }

});
fuzzybabybunny
  • 5,146
  • 6
  • 32
  • 58
  • Won't this call the meteor method at least twice because the helper is recalculated when "myResult" changes? You should probably check that "myResult" isn't set before hitting the server. – Michael Mason Jun 18 '15 at 08:59