Write modern apps with

Ember Octane

Gokul Kathirvel

Front-end Develoepr @zoho

@_gokatz | gokatz.me

A framework for
ambitiousΒ web developers.

  • Convention

  • Productivity

  • Stability

  • Community

Ember Octane

What the deal with

  • No jQuery
  • Native Classes (+Decorators)
  • Angle Bracket Syntax & Named Arguments
  • Tracked Properties
  • Glimmer Components

Native ES Class



    class TicketManager {
        totalSeats = 10;
        seatsBooked = 0;
    
        book() {
            this.seatsBooked++;
        }
    
        cancel() {
            this.seatsBooked--;
        }
    }
    

Let's see how EASYΒ is to convert a native class into an Ember Component

Generate Ember App With Octane Blueprint

ember new ticket-manager -b @ember/octane-app-blueprint
ember s

http://localhost:4200

Create a counter Component

ember g component ticket-manager

Angle Bracket Component


    
    // application.hbs
    
    <TicketManager />
    
    
    
    // components/counter.hbs
    
    <h1>Book your tickets here</h1>

Skeleton


       
    
    // components/ticket-manager.hbs
    
    <div class="ticket-manager">

      <div> Seats Booked </div>
      <div class="seats-count"> <b> 0 </b> </div>
    
      <p>
        <button class="book"> BOOK </button>
    
        <button class="cancel"> CANCEL </button>
      </p>
    
    </div>

JS State


    
    import Component from '@glimmer/component';

    // This is a perfectly 
    // valid ember component

    class TicketManager extends Component {
        totalSeats = 10;
        seatsBooked = 0;
    
        book() {
            this.seatsBooked++;
        }
    
        cancel() {
            this.seatsBooked--;
        }
    }


    class TicketManager {
        totalSeats = 10;
        seatsBooked = 0;
    
        book() {
            this.seatsBooked++;
        }
    
        cancel() {
            this.seatsBooked--;
        }
    }
    

Native Class Support

Wire Up



    // components/ticket-manager.hbs
    
    <div class="ticket-manager">

      <div> Seats Booked </div>
      <div class="seats-count"> <b> 0 </b> </div>
    
      <p>
        <button class="book"> BOOK </button>
    
        <button class="cancel"> CANCEL </button>
      </p>
    
    </div>

Wire Up



    // components/ticket-manager.hbs
    
    <div class="ticket-manager">

      <div> Seats Booked </div>
      <div class="seats-count"> <b>{{this.seatsBooked}}</b> </div>
    
      <p>
        <button class="book"> BOOK </button>
    
        <button class="cancel"> CANCEL </button>
      </p>
    
    </div>

Wire Up



    // components/ticket-manager.hbs
    
    <div class="ticket-manager">

      <div> Seats Booked </div>
      <div class="seats-count"> <b>{{this.seatsBooked}}</b> </div>
    
      <p>
        <button class="book" onclick={{action this.book}}> BOOK </button>
    
        <button class="cancel" onclick={{action this.cancel}}> CANCEL </button>
      </p>
    
    </div>

Let's Hands-On

Tracked Properties


    
    import Component from '@glimmer/component';

    class TicketManager extends Component {
        totalSeats = 10;
        seatsBooked = 0;
    
        book() {
            this.seatsBooked++;
        }
    
        cancel() {
            this.seatsBooked--;
        }
    }

    
    import Component from '@glimmer/component';
    import { tracked } from '@glimmer/tracking';

    class TicketManager extends Component {
        @tracked totalSeats = 10;
        @tracked seatsBooked = 0;
    
        book() {
            this.seatsBooked++;
        }
    
        cancel() {
            this.seatsBooked--;
        }
    }

Computed Properties


    
    import Component from '@glimmer/component';
    import { tracked } from '@glimmer/tracking';

    class TicketManager extends Component {
        @tracked totalSeats = 10;
        @tracked seatsBooked = 0;
    
        book() {
            this.seatsBooked++;
        }
    
        cancel() {
            this.seatsBooked--;
        }
        get seatsRemaining() {
            return this.totalSeats - this.seatsBooked;
        }

    }
    
    // components/ticket-manager.hbs
    
    <div class="ticket-manager">
    
       ...       

      <div class="seats">
        <div class="booked">
          <div> Seats Booked </div>
          <div class="seats-count"> 
            <b>{{this.seatsBooked}}</b> 
          </div>
        </div>
    
        <div class="remaining">
          <div> Seats Left </div>
          <div class="seats-count">
             <b>{{this.seatsRemaining}}</b> 
          </div>
        </div>
      </div>

       ...
    
    </div>

Component Arguments


    
    // application.hbs
    
    <TicketManager @theatreName="KG Cinemas" />
    
    
    
    // components/ticket-manager.hbs
    
    <h3>Theatre: {{@theatreName}}</h3>

Other Language Features

  • Conditionals
  • Template Looping
  • Routing
  • Global State Management

Conditionals


    // components/ticket-manager.hbs

    <div class="ticket-manager">
    
      <p>
        <i>
          {{#if this.seatsRemaining}}
            Book your ticket before it's gone... :)
          {{else}}
            Oops! Tickets sold out :(
          {{/if}}
        </i>
      </p>
    
      <hr>
    
      ...
    
    </div>

Looping in template


       
    
    // application.hbs

    {{#each theatres as |theatre|}}

        <TicketManager @theatreName={{theatre.title}} />        

    {{/each}}

Routing

State Management

Few exciting upcomings...

  • Code Splitting
  • Module Unification
  • Named Blocks
  • and many more...

Final Thoughts

Community

Thank You All

writing modern apps with ember octane (Ticket Manager)

By Gokul Kathirvel

writing modern apps with ember octane (Ticket Manager)

  • 1,202