Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular JS logging data with promises and local storage

I want to log actions in my angular app.

If I am not able to post then I want to add the item to another log in local storage so that next time I post I can try and add these items as well.

Once this is done I want to try and post the current items. I also want to have a (sync) button which runs through the process without going through the action log process. so that the user can try and post all the items they haven't been able to post earlier.

I am thinking of approaching it like this. on submit

-add item to local storage, then try to post. (so that it posts earlier items first)

on success

-remove item from local storage

on error

-keep item to local storage

I am a fair way down the track of getting this working as shown below, however I am not sure about whether this is the best way to approach this.

At the moment I can post the data on success but not remove the individual item from local storage.

I added in a userService called removeName which I have commented out in my below code, as it currently removes the _nameLog rather than the local storage reference to the item.

But when you run the code in the codepen demo it posts each item every time as I am not removing them on sucess?

How can I remove the local storage item on success without removing the _namelog (as this need to stay in the ng-repeat) or is there a different way I should be approaching this?

    <body ng-app="myApp">
    <div ng-controller="MyCtrl">
       <input type="text" ng-model="updatedname">
       <input type="button" value="Change name" ng-click="changeName(updatedname)"/>
       <br/>
          Hello, {{name}}! 
    <ul>
        <li ng-repeat="name in nameLog">{{name.value}} - {{name.time}}</li>
    </ul>    
         <input type="button" value="sync" ng-click="syncPosts()"/>
    </div>
    </body>

    <script>
    var myApp = angular.module('myApp',[]);
    myApp.factory('UserService', ['$window','$http', function($window,$http) {
        var _nameLog = [];
        var userService = {};
        userService.name = "John";
        userService.ChangeName = function (value) {
          userService.name = value;
        };
        userService.logName  = function (value) {
          _nameLog.push ({
            "value":value,
            "time" :Date.now()
          });
        };
        userService.removeName  = function (value) {
           return delete _nameLog[0];
        };
        userService.getNameLog = function(){ 
          return _nameLog; 
        };
        userService.setLS = function(key, value) {
          $window.localStorage[key] = value;
        },
        userService.getLS = function(key, defaultValue) {
          return $window.localStorage[key] || defaultValue;
        };
        userService.setObject = function(key, value) {
          $window.localStorage[key] = JSON.stringify(value);
        };
        userService.getObject = function(key) {
          return JSON.parse($window.localStorage[key] || '{}');
        };
        userService.testPost = function(myVal,myTime) {
          return $http.post('http://jsonplaceholder.typicode.com/posts', {title:myVal,body:myTime,userId: 1});
        };
        return userService;
    }]);

    function MyCtrl($scope, UserService) {
        $scope.name = UserService.name;
        $scope.updatedname="";
        $scope.changeName=function(data){
            $scope.updateServiceName(data);
        }
        $scope.updateServiceName = function(name){
            UserService.ChangeName(name);
            UserService.logName(name);
            $scope.name = UserService.name;
            $scope.nameLog = UserService.getNameLog();
            UserService.setLS('name', JSON.stringify($scope.nameLog));
            getPosts();
        }
        $scope.syncPosts = function(){
            getPosts();
        }
        function testPost(myVal,myTime) {  
            UserService.testPost(myVal,myTime)
              .success(function(data, status, headers, config) {
                console.log('success');
                console.log(data);
                //UserService.removeName();
              })
              .error(function(data, status, headers, config) {
                console.log('error');
            });
        }
        function getPosts(){
            getObj = UserService.getObject('name');
            for (var k in getObj) {
              var myVal = getObj[k].value;
              var myTime = getObj[k].time;
              testPost(myVal,myTime);
              console.log(getObj[k].value);
            }
        } 
    }
    </script>
like image 667
ak85 Avatar asked Nov 09 '14 03:11

ak85


1 Answers

"How can I remove the local storage item on success without removing the _namelog "

You have a few problems with your design:

1) For the local storage key=name the value is an array. In your testPost you don;t know which array item you are posting. If you knew you could retrieve that array from LS splice that element from the array and stringify it back to the LS.

2) It requires too much String to JSON back and forth.

Hence my advice is to follow a key naming scheme like name-0, name-1, name-2 and store each log entry as a separate key. Keep a counter in the LS. Increment this as you add log entry. Then in your testPost you could just delete that key. Pass k as a parameter to testPost from the getPosts.

Solution is in plunkr solution

    <body ng-app="myApp">
    <div ng-controller="MyCtrl as ctrl">
       <input type="text" ng-model="updatedname">
       <input type="button" value="Change name" ng-click="changeName(updatedname)"/>
       <br/>
          Hello, {{name}}! 
    <ul>
        <li ng-repeat="name in nameLog">{{name.value}} - {{name.time}}</li>
    </ul>    
         <input type="button" value="sync" ng-click="syncPosts()"/>
    </div>
    </body>


    angular.module('myApp', [])
      .factory('UserService', ['$window', '$http',
        function($window, $http) {
          var _nameLog = [];
          var userService = {};
          userService.name = "John";
          userService.ChangeName = function(value) {
            userService.name = value;
          };
          userService.logName = function(value) {
            var logCount = userService.getLS('count', undefined);
            if (angular.isUndefined(logCount)) {
              logCount = -1;//so that this gets incremented to 0

            } 
            var obj = {
              "value": value,
              "time": Date.now()
            };
            logCount++;

            _nameLog.push(obj);
            this.setObject('count',logCount);
            this.setObject('name#'+logCount, obj);

          };
          userService.removeName = function(value) {
            return delete _nameLog[0];
          };
          userService.getNameLog = function() {
            return _nameLog;
          };
          userService.setLS = function(key, value) {
            $window.localStorage[key] = value;
          },
          userService.getLS = function(key, defaultValue) {
            return $window.localStorage[key] || defaultValue;
          };
          userService.deleteLS = function(key) {
            return $window.localStorage.removeItem(key);
          };
          userService.setObject = function(key, value) {
            $window.localStorage[key] = JSON.stringify(value);
          };
          userService.getObject = function(key) {
            return JSON.parse($window.localStorage[key] || '{}');
          };
          userService.testPost = function(myVal, myTime) {
            return $http.post('http://jsonplaceholder.typicode.com/posts', {
              title: myVal,
              body: myTime,
              userId: 1
            });
          };
          return userService;
        }
      ])
      .controller('MyCtrl', ['$scope', 'UserService',
        function($scope, UserService) {
          $scope.name = UserService.name;
          $scope.updatedname = "";
          $scope.changeName = function(data) {
            $scope.updateServiceName(data);
          }
          $scope.updateServiceName = function(name) {
            UserService.ChangeName(name);
            UserService.logName(name);
            $scope.name = UserService.name;
            $scope.nameLog = UserService.getNameLog();
            //$scope.getPosts();
          }
          $scope.syncPosts = function() {
            $scope.getPosts();
          }
          $scope.testPost = function(myVal, myTime, k) {
            UserService.testPost(myVal, myTime)
              .success(function(data, status, headers, config) {
                console.log('success');
                console.log(data);
                //UserService.removeName();
                UserService.deleteLS('name#'+k);
              })
              .error(function(data, status, headers, config) {
                console.log('error');
              });
          }
          $scope.getPosts = function() {
            var logCount = UserService.getLS('count', undefined);
            if (angular.isUndefined(logCount)) {
              return;//there is nothing in log
            }
            for(var k = 0 ; k <= logCount ; k++) {
              var getObj = UserService.getObject('name#'+k);

              var myVal = getObj.value;
              var myTime = getObj.time;
              $scope.testPost(myVal, myTime, k);
              console.log(getObj.value);

            }
          }
        }
      ]);
like image 51
bhantol Avatar answered Oct 19 '22 04:10

bhantol