Today we'll see a solution to the previous exercise, as well as a few resources to help prepare you for the upcoming drips.

Solution

In the last Drip you were asked to continue working on our app that had a current-user service. The service grew a bit beyond the original scope and was also housing a 'remainingMessages' property that would only allow a user to post 10 messages. The exercise was to display the messages that were being created, allow the user to delete a message and keep track of the 'remainingMessages' property. There were of course several ways to accomplish this task. Let's look at one straight forward way to get this done.

I am going to use the same current-user service to keep track of our messages. If we had a proper backend, we would probably have a model for our messages, and that model would be tied to a route. But, for our purposes, we'll keep it simple. In app/services/current-user.js we can add an empty messages array. We can also change the decrementMessagesRemaining function to push a parameter to the messages array. In which case, we should probably change the name. We also need to create a deleteMessage function to remove a message from the message array. Our service might end up up looking like this:

export default Ember.Service.extend({
  messages: [],
  messagesRemaining: Ember.computed('messages.[]', function(){
    const totalPermittedMessage = 10;
    return (totalPermittedMessage - this.get('messages').length);
  }),
  userInfo: Ember.Object.create({
    id: 1,
    firstName: 'Brandon',
    lastName: 'Blaylock',
    email: 'brandon.blaylock@gmail.com',
    twitter: 'baroquon',
    github: 'baroquon',
  }),
  addMessage(msg){
    let messagesRemaining = this.get('messagesRemaining');
    if(messagesRemaining > 0){
      this.get('messages').pushObject(msg);
      return { success: true, notice: `You have ${this.get('messagesRemaining')} messages remaining.` };
    } else {
      return { success: false, notice: `You are out of messages.` };
    }
  },
  deleteMessage(msg){
    this.get('messages').removeObject(msg);
    return { success: true, notice: `This message has been removed. You have ${this.get('messagesRemaining')} messages remaining.` };
  }
});

One thing worth pointing out here is that on our computed property we are keying off of 'messages.[]'. This says that we want to invalidate our cache anytime the array is changed.

We also could update our component's JavaScript to look like this:

export default Ember.Component.extend({
  currentUser: Ember.inject.service(),
  gravatarUrl: Ember.computed('currentUser.userInfo.email', function() {
    const email = this.get('currentUser.userInfo.email');
    return `http://www.gravatar.com/avatar/${md5(email)}`;
  }),
  actions: {
    sendMessage(messageText){
      if(Ember.isPresent(messageText)){
        let sendMessage = this.get('currentUser').addMessage(messageText);
        if(sendMessage.success){
          this.set('messageText', '');
        }
        this.set('notice', sendMessage.notice);
      } else {
        this.set('notice', 'You should really type a message before you send one.');
      }
    },
    removeMessage(msg){
      let deleteMessage = this.get('currentUser').deleteMessage(msg);
      this.set('notice', deleteMessage.notice);
    }
  }
});

Finally, in our template we need to display the messages:

<img src={{gravatarUrl}}>
<br>
{{currentUser.userInfo.firstName}} {{currentUser.userInfo.lastName}}
<br>
{{currentUser.userInfo.email}}
<ul>
  {{#each currentUser.messages as |msg|}}
    <li>{{msg}} <button {{action 'removeMessage' msg}}>Delete</button></li>
  {{/each}}
</ul>
{{textarea value=messageText}}
<br>
{{notice}}
<br>
<button {{action 'sendMessage' messageText}}>Send Message</button>

That should do it. We are now listing all of our messages, keeping track of remaining messages, and we have the ability to delete messages after they have been posted.

Preparatory Miscellanea

This week we are going to be learning about tests. So, this might be a good time read up on some basics.