5. Step 5 - Implement the Update Use Case

This use case corresponds to the update operation from the four basic CRUD data management operations. The request URL path of this operation is #/updateBook.

Like for the Create use case, we have a view template for the user interface, partials/updateBook.html, which invokes a BooksController method, updateBook(). The updateBook view template has a select field for choosing the book to be updated, an output field for the standard identifier attribute isbn, and an input field for each attribute of the $scope.book view model that can be updated. Notice that by using an output field for the standard identifier attribute, we do not allow changing the standard identifier of an existing object.

<h1>Public Library: Update a book record</h1>
<form ng-init="getAllBooks()">
  <div ng-hide="book">
    <label>Select book:
      <select ng-model="book" ng-options="book.title for book in books">
        <option value="">---</option>
      </select>
    </label>
  </div>
  <div ng-show="book">
    <div>
      <label>ISBN:
        <output type="text" name="isbn" ng-bind="book.isbn" />
      </label>
    </div>
    <div>
      <label>Title:
        <input type="text" name="title" ng-model="book.title" />
      </label>
    </div>
    <div>
      <label>Year:
        <input type="number" name="year" ng-model="book.year" />
      </label>
    </div>
    <div>
      <button type="submit" name="commit" ng-click="updateBook()">
        Save Changes
      </button>
    </div>
  </div>
</form>

In the select element, the AngularJS attribute ng-model is used for establishing two-way data binding with $scope.book, while ng-options is used for retrieving the books list from $scope and populating the select element with option elements according to the expression book.title for book in books, which defines book titles as the content of the selection list options. As an additional option element, we set the text --- with an empty value for indicating that nothing has been selected.

Notice that the view template has a div section with an ng-hide attribute and another one with an ng-show attribute, both set to book. Their effect is that the first div section will be hidden, and the second will be shown, as soon as the view model object book has been assigned by the user selecting a book.

Notice also, that we can specify an ordinary, instead of a two-way, data binding with ng-bind, for only showing the value of a view model attribute, We are doing this for the output field showing the ISBN of the selected book.

Let's take a look at the BooksController method updateBook():

plControllers.controller('BooksController',
    ['$scope', '$http', function ( $scope, $http){
  ...
  $scope.updateBook = function () {
    var bookUrl = 'https://api.parse.com/1/classes/Book/';
    $http({
      method: 'PUT',
      url: bookUrl + $scope.book.objectId,
      data: {
        isbn: $scope.book.isbn,
        title: $scope.book.title,
        year: $scope.book.year
      }
    })
    .success( function () {
      alert("SUCCESS: Update book");
      $scope.book = {};
    })
    .error( function ( data) {
      alert("ERROR: Update book", data);
    });
  };
  ...
}]);

Notice how we set the url parameter such that it ends with the book's Parse objectId.