0

Not sure if I am doing this correctly. I have two controllers. One pulls all posts. the other gives me the count of all the posts in the trash can. It currently works but only one way. If I undo a post from the trash can and put it back into the population the count changes to reflect the new number but if I send a post to the trash the count does not update.

Here is my Service:

app.service('sharedProperties', function () {

});

Here is my first controller: (This controller supplies all the posts and has the trash function)

app.controller('postsCtrl', function ($scope, $log, $http, $timeout, Data, $uibModal, sharedProperties) {
    Data.get('posts').then(function(data){
        $scope.posts = data.data;
        $scope.currentPage = 1; //current page
        $scope.filteredItems = $scope.posts.length; //Initially for no filter  
        $scope.totalItems = $scope.posts.length;
        $scope.list_pages = [
                {
                    id: '5',
                    name: '5'
                }, {
                    id: '10',
                    name: '10'
                }, {
                    id: '20',
                    name: '20'
                }, {
                    id: '50',
                    name: '50'
                }, {
                    id: '100',
                    name: '100'
                }
            ];
        $scope.maxSize = 5;
    });
    $scope.setPage = function(pageNo) {
        $scope.currentPage = pageNo;
    };
    $scope.filter = function() {
        $timeout(function() { 
            $scope.filteredItems = $scope.filtered.length;
        }, 10);
    };
    $scope.sort_by = function(predicate) {
        $scope.predicate = predicate;
        $scope.reverse = !$scope.reverse;
    };
    $scope.changePostStatus = function(post){
        post.approved = (post.approved=="1" ? "0" : "1");
        Data.put("posts/"+post.id,{approved:post.approved}).then(function (result) {
            Data.toast2(result);
        });
    };
    $scope.changePostAnnounce = function(post){
        post.announce = (post.announce=="1" ? "0" : "1");
        Data.put("posts/"+post.id,{announce:post.announce}).then(function (result) {
            Data.toast2(result);
        });
    };
    $scope.trashPost = function(post){
        if(confirm("Are you sure to remove the post")){
            Data.delete("posts/"+post.id).then(function(result){
                $scope.posts = _.without($scope.posts, _.findWhere($scope.posts, {id:post.id}));
                $scope.totalItems = $scope.posts.length;
                Data.toast(result);
            });
        }
    };
    $scope.open = function (p,size) {
        var modalInstance = $uibModal.open({
          templateUrl: 'views/postsEdit.html',
          controller: 'postsEditCtrl',
          size: size,
          resolve: {
            item: function () {
              return p;
            }
          }
        });
        modalInstance.result.then(function(selectedObject) {
            if(selectedObject.save == "insert"){
                $scope.posts.push(selectedObject);
                $scope.posts = $filter('orderBy')($scope.posts, 'id', 'reverse');
            }else if(selectedObject.save == "update"){
                p.title = selectedObject.title;
                // p.price = selectedObject.price;
                // p.stock = selectedObject.stock;
                // p.packing = selectedObject.packing;
            }
        });
    };

});

Here is my second controller: (this controller counts the posts in the trashcan)

app.controller('postsTrashCtrl', function ($scope, $log, $http, $timeout, Data, sharedProperties) {
    Data.get('trash').then(function(data){
        $scope.trash = data.data;
        $scope.totalTrashItems = $scope.trash.length;
    });

});

In controller 1 the trashPost function is where I am trying to update totalTrashItems from controller 2

I know it is something small that I am missing.

UPDATE

the HTML that has the controller and variable:

<div class="container">
        <div class="row" align="center">
            <div class="stats" ng-controller="postsTrashCtrl"><i class="fa fa-thumb-tack"></i> Total Posts (<span class="attendStat">{{ totalItems }}</span>)<span class="seperator">&nbsp;&nbsp;|&nbsp;&nbsp;</span><i class="fa fa-trash-o"></i> <a href="#/trash" id="trashCan" class="trashCan">Trash</a> (<span class="attendStat">{{totalTrashItems}}</span>)</div>
        </div>
6
  • sounds like your trash can controller is wrapped inside your post controller Commented Mar 18, 2016 at 20:03
  • I am new to Angular and do not know what that means or how to resolve it Commented Mar 18, 2016 at 20:04
  • can your post your html Commented Mar 18, 2016 at 20:05
  • Just added it as an update Commented Mar 18, 2016 at 20:06
  • i don't see postsCtrl html, so, in terms of html, is postsCtrl element an ancestor of postsTrashCtrl element? Commented Mar 18, 2016 at 20:09

1 Answer 1

1

I saw that you have an empty service there.

without looking too deep into your current code. My solution for inter-controller communication for this context would be to $broadcast("customEventName") on Post, Trash and UnTrash events.

and your PostController and TrashPostController will subscribe to these broadcasted events using $on("customEventName", function(){ })

All the posting and trashing of data, and even communication with server is to be maintained using one PostTrackingService. In this case your controller will simply call the service if it need to perform anything with posting and tracking.

I know this is a bit lengthy to read through. I would suggest first look at the html, then get of a light of how those controllers work, and finally look at how the service is defined. If you apply this pattern to your code. your problem will be resolved.

Here is the code. You can also play with it on JSFiddle

<script src="https://code.angularjs.org/1.4.9/angular.min.js"></script>
<div ng-app="myApp">

  <div ng-controller="PostController">
    {{postCount}}
    <button ng-click="post()">
      Post
    </button>
    <button ng-click="trash()">
      Trash
    </button>
  </div>

  <div ng-controller="TrashController">
    {{trashCount}}
    <button ng-click="untrash()">
      UnTrash
    </button>
  </div>

</div>

<script>

var app = angular.module('myApp', []);

//----------------- Service to track all post changes ---------------
app.factory('PostTrackingService', function($rootScope) {
  var postCount = 10;
  var trashCount = 3;

  var _postTrackingService = {};

  _postTrackingService.getPostCount = function(){ return postCount};
  _postTrackingService.post = function(dataToPost){ 
    //do something with dataToPost

    postCount++;

    //broadcast a post event
    $rootScope.$broadcast("A custom POST event invented by me");
  };

  _postTrackingService.getTrashCount = function(){ return trashCount};
  _postTrackingService.trash = function(postId){
    //do something with postId

    trashCount++;
    postCount--;

    //broadcast a trash event
    $rootScope.$broadcast("A custom TRASH event invented by me");
  };

  _postTrackingService.untrash = function(postId){
    //do something with postId

    trashCount--;
    postCount++;

    //broadcast a trash event
    $rootScope.$broadcast("A custom UNTRASH event invented by me");
  };

  return _postTrackingService;
});



//----------------- Post Controller ---------------
app.controller("PostController", ["PostTrackingService", "$scope", "$rootScope", function(PostTrackingService, $scope, $rootScope){
    $scope.postCount = PostTrackingService.getPostCount();

  $rootScope.$on("A custom POST event invented by me", function(){
    $scope.postCount = PostTrackingService.getPostCount();
  });

  $rootScope.$on("A custom TRASH event invented by me", function(){
    $scope.postCount = PostTrackingService.getPostCount();
  });

  $rootScope.$on("A custom UNTRASH event invented by me", function(){
    $scope.postCount = PostTrackingService.getPostCount();
  });

  $scope.post = function(){
    PostTrackingService.post("some data to post to server");
  }

  $scope.trash = function(){
    PostTrackingService.trash("a post ID");
  }

}]);

//----------------- Trash Controller ---------------
app.controller("TrashController", ["PostTrackingService", "$scope", "$rootScope", function(PostTrackingService, $scope, $rootScope){
    $scope.trashCount = PostTrackingService.getTrashCount();

  $rootScope.$on("A custom TRASH event invented by me", function(){
    $scope.trashCount = PostTrackingService.getTrashCount();
  });

  $rootScope.$on("A custom UNTRASH event invented by me", function(){
    $scope.trashCount = PostTrackingService.getTrashCount();
  });

  $scope.untrash = function(){
    PostTrackingService.untrash("some post id");
    //make any calls to inform server
  }

}]);

</script>
Sign up to request clarification or add additional context in comments.

2 Comments

I appreciate your answer, thank you. I am not sure if I did this the best way but I took out the service and in my postsTrashCtrl I added $rootScope.totalTrashItems = $scope.trash.length; Then in my trashPost function which is inside my postsCtrl I increment totalTrashItems by 1 $rootScope.totalTrashItems++; What do you think?
@Jason $rootScope is sort of a cheating way, and surprisingly work in many contexts. lol. So if that works for you and you are short on time, sure by all means. If you have the time, play with the sample code up there. it would be more advised to use a Service for your purpose. Take some time to understand it, it will give you way more benefits in the long run.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.