Getting Started with Ember 2.0

Getting Started with Ember 2.0

In this checklist-like article, we will create a simple blog application with Ember 2.0 and Firebase!

Here we’ll focus exclusively on the how to create an Ember 2.0 application.

This article was inspired by this one. Many thanks for James Futhey.

Read the original article to understand the Whys.

You can see the live application here, and the source here.

  1. First you need to install Ember-CLI, that is the command-line interface for building Ember applications.

    1
    npm install -g ember-cli
  2. (Optional) Put an alias in your .bashrc:

    1
    alias e='ember'
  3. Create a new project with ember-cli:

    1
    e new simple-blog
  4. Upgrade Ember and Ember Data:

    1
    2
    bower install --save ember#2.0.0
    bower install --save ember-data#2.0.0-beta.1
  5. Let’s see if our upgrade was well succeed. Type on terminal:

    1
    e s

    ps: This is an alias to ember serve

    Now go to localhost:4200 to see your Welcome message :)

    See what changed in your application here.

  6. Change the structure of your application layout at app/templates/application.hbs:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <header>
    <h1>EmberBlog</h1>
    <p>
    Simple blog application written with Ember 2.0 and Firebase
    </p>
    </header>
    {{outlet}}

    See what changed here

  7. Create a Index route

    1
    e g route index
  8. Add some code in app/templates/index.hbs to verify if everything is working correctly:

    1
    <h2>Index Page</h2>

    Go to localhost:4200 to see if Index Page is beign displayed.

    See what changed here.

  9. Install the Firebase addon:

    1
    e install emberfire
  10. Create a new app on your Firebase dashboard.

  11. To connect Firebase to our application, you should edit the file config/environment.js and add on line 8 the name of your Firebase app created in the previously step. Your environment.js file will looks like it:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    module.exports = function(environment) {
    var ENV = {
    modulePrefix: 'ember-simple-blog',
    environment: environment,
    contentSecurityPolicy: { 'connect-src': "'self' https://auth.firebase.com wss://*.firebaseio.com" },
    firebase: 'https://YOUR-APP-NAME.firebaseio.com/',
    baseURL: '/',
    locationType: 'auto',
    EmberENV: {
    FEATURES: {
    // Here you can enable experimental features on an ember canary build
    // e.g. 'with-controller': true
    }
    },
    APP: {
    // Here you can pass flags/options to your application instance
    // when it is created
    }
    };

    See what changed here.

  12. Create a Post model:

    1
    e g model post title:string author:string createdDate:date text:string

    See what changed here.

  13. Edit your Post model to be able to load Ember Data pieces independently. Your app/models/post.js file should looks like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import DS from 'ember-data';
    let {
    Model,
    attr
    } = DS;
    export default Model.extend({
    title: attr('string'),
    author: attr('string'),
    createdDate: attr('date'),
    text: attr('string')
    });

    ps: Here we are using a new ES2015 feature called Destructuring :D

    See what changed here.

  14. Create a create-new-post component that will be responsible to add new posts to our app. Here we will use the POD structure.

    1
    e g component create-new-post --pod
  15. Edit the file app/components/create-new-post/template.hbs to insert the necessary elements that we need to create a new post:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <h3>Create a new post</h3>
    <form>
    <p>
    {{input value=post.title placeholder="Post title"}}
    {{input value=post.author placeholder="Author"}}
    </p>
    <p>
    {{textarea value=post.text placeholder="Content"}}
    </p>
    <p>
    <span {{action "createPost" post}} class="btn btn-submit">Publish</span>
    </p>
    </form>

    Warning! If you read the original article, you’ll notice that the logic that I implemented to create the post is different. In our future articles all of it will be thoroughly explained.

  16. Let’s refactor our Index template and add our component in it. Your app/templates/index.hbs should look like this:

    1
    {{create-new-post}}
  17. Now that we have our HTML structure, let’s add some style to it. Open your app/styles/app.css file and add the following CSS:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    * {
    font-family: 'Roboto', sans-serif;
    box-sizing: border-box;
    }
    body {
    width: 80%;
    margin: 1em auto;
    }
    .container {
    float: left;
    width: 60%;
    }
    aside {
    float: left;
    width: 20%;
    }
    header {
    background-color: #e74c3c;
    color: #fff;
    padding: 2em;
    margin-bottom: 1em;
    }
    .btn {
    padding: .5em 2em;
    border-radius: 3px;
    }
    .btn:active {
    position: relative;
    top: 1px;
    }
    .btn:hover {
    cursor: pointer;
    }
    .btn-submit {
    background-color: #c0392b;
    color: #fff;
    }
  18. To load the Roboto font you will need to do two things:

    • Add the <link> reference to that font in your app/index.html.

      1
      <link href='http://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
    • Allow that your application load that font from an external resource. To do it, edit your config/environment.js and add the contentSecurityPolicy section in your file. It will look like this:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      module.exports = function(environment) {
      var ENV = {
      modulePrefix: 'ember2-blog',
      environment: environment,
      contentSecurityPolicy: { 'connect-src': "'self' https://auth.firebase.com wss://*.firebaseio.com" },
      firebase: 'https://firember2-blog.firebaseio.com/',
      baseURL: '/',
      locationType: 'auto',
      EmberENV: {
      FEATURES: {
      // Here you can enable experimental features on an ember canary build
      // e.g. 'with-controller': true
      }
      },
      APP: {
      // Here you can pass flags/options to your application instance
      // when it is created
      },
      contentSecurityPolicy: {
      'font-src': "'self' data: fonts.gstatic.com",
      'style-src': "'self' 'unsafe-inline' fonts.googleapis.com"
      }
      };

    See what changed here.

  19. Add an action to our create-new-post component. Your app/components/create-new-post/component.js should look like this:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import Ember from 'ember';
    export default Ember.Component.extend({
    actions: {
    createPost(post) {
    this.sendAction('createPost', post);
    this.set('post', {});
    }
    }
    });
  20. Refactor our Index Route to handle the createPost method and effectively create a post. We will also add the logic necessary to return all posts that have been created. Edit the file app/routes/index.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    import Ember from 'ember';
    export default Ember.Route.extend({
    model() {
    return {
    data: this.store.findAll('post'),
    post: {}
    }
    },
    actions: {
    createPost(info) {
    let newPost = this.store.createRecord('post', {
    title: info.title,
    text: info.text,
    author: info.author,
    createdDate: new Date()
    });
    newPost.save();
    }
    }
    });
  21. Passing data to our component in Index template. Edit the file app/templates/index.hbs:

    1
    {{create-new-post post=model.post createPost="createPost"}}

    Now if you submit your form and look in your Firebase dashboard, you will be able to see that your post was created! Amazing! ;D

    We did a lot of things, wow! See all the commits that was done here.

  22. Now that we are able to create our post, we need to show it! Let’s create a component for that purpose. Run the following command:

    1
    e g component blog-post
  23. Add the structure to our blog-post component. The file app/templates/components/blog-post.hbs should look like this:

    1
    2
    3
    4
    5
    <article>
    <h2>{{post.title}}</h2>
    <p>{{post.text}}</p>
    <em>(Posted on {{post.createdDate}} by {{post.author}})</em>
    </article>
  24. Let’s refactor the Index template to list all articles that you have in your Firebase database. The file app/templates/index.hbs should now look like this:

    1
    2
    3
    4
    5
    6
    7
    8
    <div class="container">
    {{#each model.data as |post|}}
    {{blog-post post=post}}
    {{/each}}
    </div>
    <aside>
    {{#create-new-post post=model.post createPost="createPost"}}{{/create-new-post}}
    </aside>

    Awesome!!! Now, if you followed all the steps correctly, you should be able to see all your posts and to create new ones too!

    See what changed here.

We are almost done! Our application is working correctly, and now we need to deploy it. Go to this article and follow the instructions in the section “Deploying our Application“.

And that’s it!

I hope that you enjoy to build that simple but functional application with Ember 2.0!

Cheers! =)