d3trax
1/17/2014 - 7:56 AM

A simple, made-up example of the code for a simple AngularJS blog viewer as a more detailed exploration of http://benhollis.net/blog/2014/01

A simple, made-up example of the code for a simple AngularJS blog viewer as a more detailed exploration of http://benhollis.net/blog/2014/01/17/cleanly-declaring-angularjs-services-with-coffeescript/ . Yes, I know about $resource, but I prefer not to use it.

app = angular.module 'BlogExample', []

# Simple controller that loads all blog posts
app.controller 'BlogCtrl', ['$scope', 'Blog', ($scope, Blog) ->
  # Get all the blog posts
  Blog.all().then (posts) ->
    $scope.posts = posts
    
  # Extend the $scope with our own properties, all in one big block
  # I like this because it looks like declaring a class.
  angular.extend $scope,
    posts: []
    
    # A new, prototype post that will be bound to the "new post" form.
    newPost: Blog.newPost()
    
    # When the "save post" button is clicked:
    addPost: ->
      $scope.newPost.save().then ->
        @posts.push $scope.newPost
        $scope.newPost = Blog.newPost()
]

# The Blog service provides access to Posts. We immediately "new" the class
# to provide a single instance of the Blog class to the injector.
app.factory 'Blog', ['$http', 'Post', ($http, Post) ->
  new class Blog
    # Get all blog posts
    all: ->
      # Assume a response like:
      # { "posts": [ { "title": "Hello World", "author": "Ben Hollis", "body": "This is an example." } ] }
      $http.get('/posts').then (result) ->
        new Post(post.title, post.author, post.body, true) for post in result.data.posts
    
    # Create a new, empty blog post
    newPost: ->
      new Post('', '', '')
]

# This makes the Post class available for injection, rather than an instance of Post. Thus, it doesn't call "new".
#
# Post represents a single blog post.
app.factory 'Post', [ '$http', ($http) ->
  class Post
    # Title, Author, and Body are self-explanatory
    # Persisted tells whether this instance has been saved.
    constructor: (@title, @author, @body, @persisted = false) ->
      
    # Save this post to the server.
    save: ->
      $http.post('/posts', title: @title, author: @author, body: @body).then =>
        @persisted = true
]