/angularjs/

AngularJS – Example App - Part 2

2014-06-29 15:14:05

In this episode we have to solve some business problem.

  • _System should remember all changes in post form, even when user didn't click save. It's important to not save "dirty" data in database. Use for that Local Storage. _

To accomplish this task we will use angular-local-storage.

Here we have our service. Now it works only with "post" object. I think in near future we will change that to more generic solution, but for now it's enough. Inside we have method for: - add post object to local storage - get all posts (we want mark cached post on list with red star and also we will prepare seperate list with all cached posts) - get one post (we want mark post as cached in details' page and show in form version which wasn't saved). User will have two options in that situation, he can click cancel "button" or "save". If he click "save", we use data from cache to overwrite data in database and we will remove post form cache. "Cancel" option remove only post from cache.

service.localPostStorage.js

angular.module('LouisApp.service', ['LocalStorageModule'])

    .service('LocalPostStorage', function (localStorageService) {

        var self = this;

        this.init = function ($scope) {
            $scope.$watchCollection('post', function (newValues, oldValues) {
                if ($scope.postform.$dirty) {
                    self.add($scope.post);
                }
            });
        }

        this.add = function (postObj) {

            if (postObj.id == undefined) {
                return;
            }

            if (localStorageService.get('posts') == null) {
                localStorageService.set('posts', {});
            }

            var posts = localStorageService.get('posts');

            postObj.dirty = true;
            posts[postObj.id] = postObj;

            localStorageService.set('posts', posts);
        }

        this.getAll = function () {
            return localStorageService.get('posts');
        }

        this.isCached = function (id) {
            if (self.get(id) == undefined) {
                return false
            }
            return true;
        }

        this.get = function (id) {
            var posts = localStorageService.get('posts');
            if (posts == undefined) {
                return;
            }
            return posts[id];
        }

        this.remove = function (id, callback) {
            var posts = localStorageService.get('posts');
            if (posts == undefined) {
                return;
            }
            delete posts[id];
            localStorageService.set('posts', posts);
            if (callback) callback();
        }

        this.tagCached = function (posts) {

            posts.forEach(function (post) {
                if (self.isCached(post.id)) {
                    post.dirty = true;
                }
            });
        }
    })

;

Hmmm, but when we save this item? That's good question. For this we can use $scope.postform.$dirty, this variable informs us when user changed something.

The next step is to add LocalPostStorage Service to our controller.

angular.module('LouisApp.controllers.post', [])

    .controller('PostListCtrl', function ($scope, PostsFactory, PostFactory, $location, LocalPostStorage) {

        // ...

        $scope.posts = PostsFactory.all(function () {
            LocalPostStorage.tagCached($scope.posts);
        });
    })

    .controller('PostDetailCtrl', function ($scope, $routeParams, PostFactory, $location, LocalPostStorage) {

        LocalPostStorage.init($scope);

        $scope.save = function () {
            delete $scope.post.dirty;
            LocalPostStorage.remove($scope.post.id);
            //..
        };

        $scope.cancel = function () {
            LocalPostStorage.remove($scope.post.id, function () {
                $location.path('/post');
            });
        };

        // get data from cache
        $scope.post = LocalPostStorage.get($routeParams.id);

        //..
    })
;

Above we have parts of code for post controller.

To start monitoring the post form we have to use init method form out service when user will change something ($scope.postform.$dirty == true) then we have to add this dirty post to local storage self.add($scope.post)

LocalPostStorage.init($scope);

Mark item as cached if they exist in local storage. We do that because we have to mark item in list.

$scope.posts = PostsFactory.all(function () {
      LocalPostStorage.tagCached($scope.posts);
});

and the last step, when user click save or cancel we have to remove cached item form local storage

$scope.cancel = function () {
    LocalPostStorage.remove($scope.post.id, function () {
        $location.path('/post');
    });
};

Post list with marked items that wasn't saved.

List with all not saved items.

Here you can find a example app for this stage. One remark, it is not full working version because in this version backend not exist.

All code for this episode you can find on GitHub