Search code examples
ember.jsember-clihandlebars.js

Conditionals in templates with data fetched with getJSON


I'm trying to figure out how to do something incredibly simple: Use conditionals in templates with data fetched with getJSON. I need to show info based on the type key on the JSON hash. As an example, I've included a HBS file of what'd I'd like to do. What is the Ember Way™ to accomplish this?

Company route:

// routes/company.js

import Ember from 'ember';

export default Ember.Route.extend({
    model: function(params) {
        return this.store.findRecord('company', params.company_slug);
    },
    setupController: function(controller, model) {
        this._super(controller, model);

        Ember.$.getJSON('/companies/%@/events.json'.fmt(model.get('slug'))).then(data => {
            controller.set('events', data);
        });
    }
});

Company show template with example of what I'd like to do:

<ul class="test">
    <li>lol</li>
    {{#each events as |event|}}
        <li class="{{event.type}}">
            {{event.title}}

            {{!-- This code will obviously not work: --}}
            {{#if event.type == 'company_event'}}
               show company event stuff
            {{/if}}
            {{#if event.type == 'user_event'}}
               show user event stuff
            {{/if}}

        </li>
    {{/each}}
</ul>

Example of JSON data:

[
    {
        title: "test test test",
        type: "company_event",
        date: "2015-10-14T00:00:00.000+02:00"
    }
]

Solution

  • There are two suggestions I can think of:

    1. http://emberobserver.com/addons/ember-truth-helpers

    {{#if (eq event.type 'company_event')}}
      show company event stuff
    {{/if}}
    

    2.a. {{component}}

    You would have a company_event and a user_event component (you would need to dasherize the names to comply with the naming rules), and do something like:

    {{component event.type event}}
    

    2.b. Wrap it in a component

    Another possibility with components is to wrap the whole thing in a component and use computed properties:

    {{#each events as |event|}}
      {{li-event event=event}}
    {{/each}}
    
    // components/li-event.js
    export default Ember.Component.extend({
      tagName: "li",
      classNameBindings: ['event.type'],
    
      isCompanyEvent: Ember.computed.equal('event.type', 'company_event'),
      isUserEvent: Ember.computed.equal('event.type', 'user_event')
    });
    
    // templates/components/li-event.js
    {{event.title}}
    
    {{#if isCompanyEvent}}
      show company event stuff
    {{/if}}
    {{#if isUserEvent}}
      show user event stuff
    {{/if}}
    

    Which option to choose is left as an exercise for the reader ;)