How to use and condition in if statement on meteor template? - meteor

I want to use the and condition in if statement like
{{#if requiredExp equals 0 and tile equals "SSE"}}
Expierince cannot be equal to 0
{{/if}}
How to write this condition using and in meteor template?

Meteor is designed in a way that you can't put logic in your templates. You can create a simple helper like equals, but you cannot use logic operators like && and || in templates because this logic does not belong to templates.
You could create a global template helper equals for this:
Template.registerHelper('equals', function(param1, param2) {
return param1 === param2;
});
So you can use it in your templates:
{{#if equals requiredExp 0}}
{{#if equals tile "SSE"}}
Expierince cannot be equal to 0
{{/if}}
{{/if}}
Or, the better option is to create a helper that handles the logic you want:
Template.yourTemplateName.helpers({
showExperienceNotification: function() {
return this.requiredExp === 0 && this.tile === 'SSE';
}
});
And use it in your template:
<template name="yourTemplateName">
{{#if showExperienceNotification}}
Experience cannot be equal to 0
{{/if}}
</template>
You can access template data via keyword this in your helper:
this.requiredExp and this.tile. Read more about Meteor templates and data context: https://www.discovermeteor.com/blog/a-guide-to-meteor-templates-data-contexts/

Related

Using an "if not x" statement in an HBS template file

How can I write an if not x statement in an HBS template file?
At present, I use an if/else clause in order to achieve that:
{{#if x}}
{{else}}
Some Text
{{/if}}
Is there a way to simplify this and use a single if statement?
I've tried stuff like {{#if !x}} and {{#if ^x}}, but it didn't work of course.
Looking on the web for HBS logical operators, I couldn't quite find the syntax for a logical-not.
Update
I should emphasize that in my case x is undefined.
I've learned it "the hard way", while trying:
{{#if not x}}
Some Text
{{/if}}
Which threw TypeError: Cannot read property 'includeZero' of undefined.
Have you tried unless?
<div class="entry">
{{#unless license}}
<h3 class="warning">WARNING: This entry does not have a license!</h3>
{{/unless}}
</div>
You can use the unless helper as the inverse of the if helper. Its
block will be rendered if the expression returns a falsy value.
https://handlebarsjs.com/builtin_helpers.html
You can also considers custom helpers:
Handlebars.registerHelper("ifNot", function(a, options){
if (!a) {
return options.fn(this);
}else{
try{
return options.inverse(this);
}catch(e){
//no else statement
}
}
});

Meteor templates, check if with or

I want to check a condition with or. how is it possible?
{{#if $.Session.equals 'showField' 'edit'}}
or
{{#if $.Session.equals 'showField' 'add'}}
As Blueren and Iiro said:
{{#if or ($.Session.equals 'showField' 'edit') ($.Session.equals 'showField' 'add') }}
Then in clien/helpers folder make a js file and put this:
Template.registerHelper('or',(a,b)=>{
return a || b;
});

Reuse Meteor template as inclusion with different helpers

I'd like to re-use a Meteor template as an inclusion (i.e. using {{> }}) in two different contexts. I know I can pass in different data with the inclusion by using {{> templateName data1=foo data2=bar}}, but I'm struggling to figure out how I can provide different helpers based on the context. Here's the template in question:
<template name="choiceQuestion">
<div class="choice-grid" data-picks="{{numberOfPicks}}" data-toggle="buttons">
{{! Provide for the user to make multiple selections from the multiple choice list }}
{{#if hasMultiplePicks}}
{{#unless canPickAll}}<span class="help-block text-center">Pick up to {{numberOfPicks}}</span>{{/unless}}
{{#each choices}}
<label class="btn btn-default"><input type="checkbox" class="choice" name="{{this}}" autocomplete="off" value="{{this}}" checked="{{isChecked}}"> {{this}}</label>
{{/each}}
{{/if}}{{! hasMultiplePicks}}
{{#if hasSinglePick}}
{{#each choices}}
<label class="btn btn-default"><input type="radio" class="choice" name="{{this}}" id="{{this}}" autocomplete="off" value="{{this}}" checked="{{isChecked}}"> {{this}}</label>
{{/each}}
{{/if}}{{! hasSinglePick}}
</div>
</template>
and here's how I've reused it:
{{> choiceQuestion choices=allInterests picks=4}}
The key component of the template is a checkbox. In one context, it will never be checked. In another, it may be checked based on the contents of a field in the user document. I've added checked={{isChecked}} to the template. I've read this boolean attribute will be omitted if a falsey value is returned from the helper which should work well for my purposes.
The template's JS intentionally does not have an isChecked helper. I had hoped I could provide one on the parent where the template is included in the other context in order to conditionally check the box by returning true if the checked conditions are met, but the template doesn't acknowledge this helper.
Here's the template's JS:
Template.choiceQuestion.helpers({
hasSinglePick: function() {
return this.picks === 1;
},
hasMultiplePicks: function() {
return this.picks > 1 || !this.picks;
},
numberOfPicks: function() {
return this.picks || this.choices.length;
},
canPickAll: function() {
return !this.picks;
},
});
and the parent's JS:
Template.dashboard.helpers({
postsCount: function() {
var count = (Meteor.user().profile.posts||{}).length;
if (count > 0) {
return count;
} else {
return 0;
}
},
isChecked: function() {
return (((Meteor.user() || {}).profile || {}).contentWellTags || []).indexOf(this) > -1 ? 'checked' : null;
}
});
Template.dashboard.events({
'click .js-your-profile-tab': function(){
facebookUtils.getPagesAssumeLinked();
}
});
I've tried a few other approaches as well. I tried passing the helper to the template along with the other context (i.e. {{> templateName data1=foo data2=bar isChecked=isChecked}}. This kinda works, but it calls the helper immediately. This breaks these since I need to use a value from the context to determine what to return from my helper. Since this value doesn't exist when the function returns, the function always returns undefined.
If I return a function from this helper rather than the value and then pass the helper into the template inclusion along with the data context, I get better results. In fact, my console logs show the desired output, but I still don't end up with the checked box I expect.
Here's what that looks like. Returning a function:
isChecked: function() {
var self = this;
return function() {
return (((Meteor.user() || {}).profile || {}).contentWellTags || []).indexOf(this) > -1 ? 'checked' : null;
};
}
and passing that to the template:
{{> choiceQuestion choices=allInterests picks=4 isChecked=isChecked}}
Is there an established pattern for overriding template helpers from the parent or for including helpers on the parent that are missing from the child template? How can I achieve this?

if else in handle bar template

In need to check this scenario using handle bar templates
if(data.Id==1 && Isreal==false)
{
//`enter code here
}
else if(data.id==2 && IsReal==true)
//other html
else
`//enter code here`last html
How can I do that, I tried using helper but it is not working in my case
Best practice is to not do any business logic in the template but instead do it before and pass it through the context into the template.
i.e.
var context = {
dataOneNotReal = data.Id==1 && Isreal==false,
dataTwoIsReal = data.id==2 && IsReal==true
};
then in the template
{{#if dataOneNotReal}}
// code
{{else}}
{{#if dataTwoIsReal}}
// code
{{else}}
// code
{{/if}}
{{/if}}

More elegant helper for Meteor 0.9.3 templates

I've created a custom block helper for Meteor 0.9.3 using information from the following URL:
https://github.com/meteor/meteor/wiki/Using-Blaze#new-pattern-for-defining-custom-block-helpers
It can be used within a Spacebars template like so:
{{#ifEqual value1="stringOrNumber_1" value2="stringOrNumber_2"}}
<h1>The values ARE equal!</h1>
{{else}}
<h1>The values are NOT equal!</h1>
{{/ifEqual}}
Here is the code:
<template name="ifEqual">
{{#if isEqual value1 value2}}
{{> UI.contentBlock}}
{{else}}
{{> UI.elseBlock}}
{{/if}}
</template>
Template.ifEqual.isEqual = function (value1, value2) {
return value1 === value2;
};
My question is:
Is there a possible way to make this less clunky?
I would much prefer code that can be used within a template like so:
{{#ifEqual "stringOrNumber_1" "stringOrNumber_2"}}
...
I would register a global equals helper:
Template.registerHelper('equals', function(value1, value2){
return value1 === value2
})
And then use it like this:
{{#if equals "abc" "abc"}}
<p>They're equal :)</p>
{{else}}
<p>They're not equal :(</p>
{{/if}}
Though, you may be interested in using the underscore-helper package instead, so you don't have to define this (and similar) helpers yourself.

Resources