Template helper returning a number, change appearance based on result being positive or negative number

I’m pulling some data from APIs and using reactive vars. I am now needing to display some results on my page so I’ve created a template helper to do so. In the helper I have a function which returns a positive or negative percentage (ex. 25.61% or -25.61%). Everything seems to work fine and I can display this number on my page, but I would like to have it so the way it appears is different based on whether the number is positive or negative.

Here are a couple screenshots for example:


If the result returns as a positive number I would like to have it so it returns in green with the green upwards arrow, and if it returns negative display in red with the downwards arrow.

Here is my helper, sum1 and sum2 are reactive vars in my API result, this does a calculation for me to get a percentage comparison between two time periods:

Template.apps.helpers({
  subscribersPercentageCompare: function () {
    var sum1 = Template.instance().netSubscribersPrevious30DaysTotal.get();
    var sum2 = Template.instance().netSubscribers30DayTotal.get();
    var sum3 = sum2 - sum1;
    var sum4 = sum3 / sum1;
    var sum5 = sum4 * 100;
    var sum6 = sum5.toFixed(2) + '%';
    return sum6;
  }
});

And this is currently how it looks in my template for positive and then negative (as of now it doesn’t take into consideration whether the result is positive or negative):

<div class="stat-percent font-bold text-navy">{{subscribersPercentageCompare}}<i class="fa fa-level-up"></i></div>

<div class="stat-percent font-bold text-danger">{{subscribersPercentageCompare}} <i class="fa fa-level-down"></i></div>

I feel like it should be fairly simple but I’m a bit lost on how I can achieve this, any help would be greatly appreciated.

Haven’t used Blaze in a while but it should be as easy as creating another helper like isPercantagePositive which takes the output of subscribersPercentageCompare as an argument like

{{#if isPercentagePositive subscribersPercentageCompare}}
  A
{{else}}
  B
{{/if}}

Hope the syntax is correct :smile:

1 Like

Thanks for the info!

In my template I have made it like this:

{{#if isPercentagePositive subscribersPercentageCompare}}
    <div class="stat-percent font-bold text-danger">{{subscribersPercentageCompare}} <i class="fa fa-level-down"></i></div>
{{else}}
    <div class="stat-percent font-bold text-navy">{{subscribersPercentageCompare}} <i class="fa fa-level-up"></i></div>
{{/if}}

I’m a little bit stuck on making the isPercentagePositive helper though, I was thinking something like this?:

Template.apps.helpers({
  subscribersPercentageCompare: function () {
    var sum1 = Template.instance().netSubscribersPrevious30DaysTotal.get();
    var sum2 = Template.instance().netSubscribers30DayTotal.get();
    var sum3 = sum2 - sum1;
    var sum4 = sum3 / sum1;
    var sum5 = sum4 * 100;
    var sum6 = sum5.toFixed(2) + '%';
    return sum6;
  },
  isPercentagePositive: function () {
    if(sum5 < 1)
      return true;
  }
});

Although sum5 would appear at “undefined”, I tried using a reactive var for the output of subscribersPercentageCompare as well but that didn’t seem to work either so I’m guessing I’m just doing something wrong here…

You can do this by registering a global template helper that returns t/f based on a number’s negativity; this is more application-agnostic (meaning can be used in any application without changing anything) than the second way of solving this. This approach will put the comparison in your template.

This second way would be to return a class name instead of t/f, again based on a number’s negativity. In this case, you would probably need to change class names if you decided to use the code in another application. This approach will put the comparison in your helper.

This helper returns true for values below zero:

Template.registerHelper('isBelowZero', function(number){
    return number < 0
})

Then in the template:

{{#if isBelowZero subscribersPercentageCompare}}
    <div class="stat-percent font-bold text-navy">{{subscribersPercentageCompare}}<i class="fa fa-level-up"></i></div>
{{else}}
    <div class="stat-percent font-bold text-danger">{{subscribersPercentageCompare}} <i class="fa fa-level-down"></i></div>
{{/if}}

And these return different class names based on negativity:

Template.registerHelper('divClassByZero', function(number){
    return number < 0 ? 'text-danger' : 'text-navy'
})

Template.registerHelper('faClassByZero', function(number){
    return number < 0 ? 'fa-level-down' : 'fa-level-up'
})

Then in the template:

{{subscribersPercentageCompare}}
1 Like

The sum would be provided as an argument, so if you want to stick with that sum5 var, you could just change it to isPercentagePositive: function (sum5) {. But I’d change it to something more expressive. Remember that you’ll have to remove that % sign from the value and convert it to a number:

isPercentagePositive: function (percentage) {
  percentage = percentage.replace('%', '');
  return Number(percentage) > 0;
}
1 Like

@necmettin Thanks for the detailed reply! This helped me get it all working, very much appreciated! :smiley:

@fvg Thanks for the help! I was forgetting to remove the % sign so I appreciate that info. Got it all working now :slightly_smiling:

You could also make your helper return an object that has 3 properties: text type, value and icon :wink:

1 Like