Creating functional components in Ember JS in Open Event Front-end

In the Open Event Front-end using Ember JS we are creating a functional ticket ordering component which lets users select the amount of tickets and update the total & subtotal price accordingly. How are we doing it?

Creating a component

Components in ember are modular widgets which are used to define a single HTML element, as an independent element. Components can be reused without any dependencies across the project. This provides us a modular architecture to define a component once and reuse it across the project.

For creating a new component use:

ember g component ticket-component

In ember all components must have at least one hyphen in their name. This is an Ember convention, but it is an important one as it ensures there are no naming collisions with future HTML elements. After execution of the above command three new files are generated in the project under:

  • app/components: Contains the logic of the component.
  • app/templates: Contains the view of the component.
  • tests/integration/components: Contains all tests related to component.

Passing an array of ticket detail to template

We can pass data from APIs to the templates using ember-data, but for simplicity we are passing an array of dummy data to get it working. To pass the array to the template we need to add the following JSON to the application controller under controllers/application.js in the application.

tickets:[
  {
    description: 'Discounted ticket for all community members',
    date: 'Mon, May 22',
    price: 40.50,
    name: 'Community Ticket',
    type: 'paid',
    id: 1,
    quantity: 10,
    orderQuantity: 0,
    min: 0,
    max: 5
  }
]

For passing the data to the component template we need to pass the above object to the template using the following syntax in the application.hbs route.

{{public/ticket-component tickets=tickets}}

Rendering ticket details

We iterate over the tickets array passed by application.hbs using each handlebars helper, and we are also using semantic ui dropdown.

For computing subtotals we are using a ember-math-helpers which can be installed using

ember install ember-math-helpers

The semantic ui dropdown is used for selecting the number of orders. This allows us to bind a hidden field for storing the selected value from the dropdown.

{{#ui-dropdown class='compact selection' forceSelection=false}}
 {{input type='hidden' id=(concat ticket.id '_quantity') value=ticket.orderQuantity}}
{{/ui-dropdown}}

For downloading semantic-ui to the project we use:

ember install semantic-ui-ember

Computing subtotal using ember-math-helpers using the mult function which multiplies the price of tickets and the number of order selected from the dropdown.

<td id='{{ticket.id}}_subtotal' class="ui right aligned">
  $ {{number-format (mult ticket.orderQuantity ticket.price)}}
</td>

Computing total price of ordered tickets

To compute total price we are using computed properties which lets us observe properties in the component and compute other properties which are dependent on it. We add a computed property for the orderQuantity property associated with each of the tickets and update the total accordingly.

total: computed('tickets.@each.orderQuantity', function() {
  let sum = 0.0;
  this.get('tickets').forEach(ticket => {
    sum += (ticket.price * ticket.orderQuantity);
  });
  return sum;
})

This ensures an update of the total if any changes are made to the orderQuantity property of any ticket.