Devshop September

Meteor Göteborg

Agenda

  • Install Meteor (0.9.2)
  • Install Meteorite
  • Introduction
  • Setup
  • Iron Router + Templates + Forms
  • Publications
  • Subscriptions
  • Theming

Install latest Meteor

curl https://install.meteor.com/ | sh

Update to Meteor 0.9.2

meteor update

Introduction

  • We will build a race timer app with timers per each participants per race
  • Start by bootstrapping with the github repository
  • Try to solve each problem before we show the solution, each step (except step1) contains our solutions.
  • Learn about Pub/Sub and Iron Router
studiointeract/meteor-multi-timer

Setup

  1. Clone the sample application

     
  2. Start the application
git clone git@github.com:studiointeract/meteor-multi-timer.git
cd meteor-multi-timer
git checkout step1
meteor

#step1

https://slides.com/timbrandin/devshop-september

Iron Router 

  1. Stop the application

     
  2. Add iron:router from Atmosphere (new)

     
  3. Start the application again
CTRL + C
meteor add iron:router
meteor

#step2

Home route

  1. Create a home route



     
  2. Create a home template listing races
Router.map(function (){
  this.route('home', {
    path: '/'
  });
});
<template name="home">
  <ul>
    {{#each races}}
    <li>
      <a href="/race/{{_id}}">{{name}}</a>
    </li>
    {{/each}}
  </ul>
</template>

client/routes.js

client/views/home/home.html

#step2

Adding races

  1. Add a form to input new races to home



     
  2. Create a submit handler that adds the race
...
</ul>
<form>
  <input type="text" placeholder="Add a race">
  <button type="submit">Add</button>
</form>
</template>
Template.home.events({
  'submit form': function(event, template) {
    event.preventDefault();
    var name = template.find('input').value;
    template.find('input').value = '';

    Races.insert({name: name});
  }
});

client/views/home/home.js

client/views/home/home.html

#step2

Race route

  1. Create a race route



     
  2. Create a race template listing participants
...
  this.route('race', {
    path: '/race/:_id'
  });
});
<template name="race">
  <ul>
    {{#each participants}}
    <li>
      {{name}}
    </li>
    {{/each}}
  </ul>
</template>

client/views/race/race.js

client/routes.js

#step2

Adding participants

  1. Add a form to input new participants



     
  2. Create a submit handler that add a person
...
</ul>
<form>
<input type="text" placeholder="Add a participant">
<button type="submit">Add</button>
</form>
</template>
Template.race.events({
  'submit form': function(event, template) {
    event.preventDefault();
    var name = template.find('input').value;
    template.find('input').value = '';

    var _race = Routes.current().params._id;
    Participants.insert({name: name, _race: _race});
  }
});

client/views/race/race.js

client/views/race/race.html

#step2

Add collection data to the templates

  1. Fetch data from the Races collection



     
  2. Fetch data from the Participants collection
...
this.route('home', {
  path: '/',
  data: function() {
    return {
      races: Races.find()
    }
  }
});
...
...
this.route('race', {
  path: '/race/:_id',
  data: function() {
    return {
      participants: Participants.find({_race: this.params._id})
    }
  }
});
...

client/routes.js

client/routes.js

Step2

Checkout step2 options

  • Stash your changes and checkout

     
  • Commit your changes to your own branch
git stash
git checkout step2
git checkout -b my-step1
git commit -am "My changes to step1"
git checkout step2

Publications

  1. Remove the autopublish package

     
  2. Start the application again

     
  3. No data should be visible in the browser
meteor remove autopublish
meteor

Setup publications

  1. Create a races publication on the server




     
  2. And one for a single race, also returning participants
...
if (Meteor.isServer) {
  Meteor.publish('races', function() {
    return Races.find();
  });
}
...
  Meteor.publish('race', function(_race) {
    var race = Races.find({_id: _race});
    var participants = Participants.find({_race: _id});
    return [race, participants];
  });
...

collections/participants.js

collections/races.js

#step3

Setup subscriptions

  1. Add a subscription for races to the home route.




     
  2. And one for a single race on the race route.
...
  this.route('home', {
    path: '/',
    waitOn: function() {
      return Meteor.subscribe('races');
    },
...
...
  this.route('race', {
    path: '/race/:_id',
    waitOn: function() {
      return Meteor.subscribe('race', this.params._id);
    },
...

client/routes.js

#step3

client/routes.js

Step3

Checkout step3 options

  • Stash your changes and checkout

     
  • Commit your changes to your own branch
git stash
git checkout step3
git checkout -b my-step2
git commit -am "My changes to step2"
git checkout step3

Timing

  1. Create helpers for timer formatting, a session variable and click to start/stop.



     
  2. Show the timer in the template
Template.race.events({
...
  'click li': function() {
    if (!this.timestamp) {
      Participants.update({_id: this._id}, {$set: {timestamp: (+new Date)}});
    }
    else if (this.end) {
      Participants.update({_id: this._id}, {
        $set: {
          timestamp: (+new Date),
        },
        $unset: {
          end: true
        }
      });
    }
    else {
      Participants.update({_id: this._id}, {$set: {end: (+new Date)}});
    }
  }
});

Template.race.helpers({
  timer: function() {
    var time = Math.max(0, Session.get('now') - this.timestamp);
    return moment.utc(time).format("mm:ss.S");
  },

  finish: function() {
    var time = Math.max(0, this.end - this.timestamp);
    return moment.utc(time).format("mm:ss.S");
  }
});

Meteor.setInterval(function() {
  Session.set('now', (+new Date));
}, 100);
...
    <li>
      <span class="timer">
        {{#if end}}
          {{finish}}
        {{else}}
          {{timer}}
        {{/if}}
      </span>
      {{name}}
    </li>
...

client/views/race/race.html

#step4

client/views/race/race.js

Step4

Checkout step4 options

  • Stash your changes and checkout

     
  • Commit your changes to your own branch
git stash
git checkout step4
git checkout -b my-step3
git commit -am "My changes to step3"
git checkout step4

Devshop September 2014

By Tim Brandin

Devshop September 2014

  • 1,386
Loading comments...

More from Tim Brandin