Template helpers and collection


#1

Hi,

I’m running into a problem for which i haven’t found a solution yet. It may be simple.

In my template file, i am loading this collection which has been dynamically created. I’ll keep it down to a single object:

{"sites":
   {
    "creationDate":       "2015.03.30",
    "name":               "My Site",
    "description":        "A beautiful thing"
  }

}

From that collection, i’m creating links and creationDate for each item in my template. Like so:

<template name="sitesList">
	<div id="sidebar">
		<h4>Active Sites</h4>
		<ul id="siteslist" class="list-unstyled">
			{{#each sites}}
				<li><a href="mySites/{{cleanedString name}}">{{name}}</a> | <span id="date">{{creationDate}}</span> <i class="fa fa-times delete"></i></li>
			{{/each}}
		</ul>
	</div>
</template>

Notice that in the following line, i’m calling a template helper named cleanedString that i use to strip white spaces and replace them with dashes, to lowercase the whole string and to sanitize the input:

<a href="mySites/{{cleanedString name}}">

Because i’m using the djedi:sanitize-html package, i need to run the sanitize function on the server. It is defined this way:

Template.sitesList.helpers({
  'cleanedString': function(string) {
     Meteor.call('sanitize', string, function(err, res) {
       if (err) {
         console.log(err);
       } else {
         console.log(res);
         return res;
       }
     });
   }
});

While on the server side, the sanitize function is declared like so:

Meteor.methods({
      sanitize: function(string) {
         var saneString = sanitizeHtml(string);
         // Replaces whitespace by dash, lowercase and return as string
         var strippedStr = saneString.replace(/ /g,'-').toLowerCase(); 
         console.log(strippedStr);
         return strippedStr;
     }
});

Now here is the problem. That line can’t seem to resolve to anything else than blankness:

<a href="mySites/{{cleanedString name}}">

But certainly, the variable name containing the “My Site” value from the collection is passed to the cleanedString function. I know it because my console.log calls both from the server AND from the client are sending back the right value: “my-site”.

It seems like the problem is either with the evaluation of the template either with my code.

Anyone has any idea what did i do wrong?


#2

I think your cleanedString helper does not return anything (no return line), hence your issue.

If you really want to sanitize server-side, you can declare a ReactiveVar in your template, return it in cleanedString, and set its value in the method callback (instead of return res, which is useless).

But you might want to sanitize client-side instead, for example using Universe HTML Purifier.


#3

The issue is because Meteor.call() uses a callback function, by the time the Method completes the scope of the callback is lost and you lose your return value.

edit: As Steve said, even if the callback worked, your helper doesn’t return any value…


#5

Thanks both of you. I’ll try to figure out a solution.
Maybe use of Meteor._wrapAsync


#6

If you are doing all of this just to make a URL, why don’t you just use the native encodeURIComponent() to make it a safe URL.

I am sure that you’re wanting to make the name look pretty too - you could run a regex over the name to replace spaces with dashes first and whatnot.

Also I have this bookmarked: Slugged Routes by Meteorchef - but haven’t looked through it yet.


#7

Thanks for the ressources but since i’m working on a local project, the url doesnt matter that much to me, although it is being sanitized.

What matter most is how i am going to pass the return value from the Meteor.call method to the cleanedString helper function from within.