0

Ok, so I know what the issue here is. I'm using a $watch, and because of the value I'm setting (by calling a function in my service), a new array is created every time, and the watch constantly finds a new value. My question though, is how to fix this. My current set up is like this (only including relevant portions of code):

clientCtrl.js

.controller('ClientCtrl', function($scope, $ionicModal, $ionicPopup, $stateParams, clientService, opportunityService) {
  $scope.id = $stateParams.clientId;
  $scope.clients = clientService.getClients();
  $scope.opportunities = opportunityService.getOpportunities($scope.id);

  $scope.$watch(
    function(){ return opportunityService.opportunities },

    function(newVal) {
      $scope.opportunities = newVal;
    }
  );

opportunityService.js

.service('opportunityService', function($http) {
    this.getOpportunities = function(id) {
        this.results = [];
        if ( typeof id == 'undefined') {
            this.results = this.opportunities;
        }
        else {
            for (var a=0; a<this.opportunities.length; a++) {
                if (this.opportunities[a].clientId == id) {
                    this.results.push(this.opportunities[a]);
                }
            }
        }
        return this.results;
    };

Inefficient code aside, basically what's being done here is that the service gets a JSON object (not shown) which is stored in this.opportunities. The getOpportunities function allows me to return that to the controller. On my view, I have a list of the opportunities where I can add, edit, and delete. When I add a new opportunity (via a popup modal) it doesn't show up in the view until I navigate to a different page in my app and then return.

Essentially, adding an item works, but I would like it to show up without having to navigate away. I attempted to solve this by adding the $watch, and while it was an effective solution, I received the $digest iteration errors. I'd prefer to get rid of them now so that they don't cause any future issues.

Is there a better way to get my view to update when I add an item without having to navigate away, keeping in mind that the JSON object storing the items is in the service, and relies on the passing of an ID parameter?

  • How does the modal modify (add or remove) the list of opportunities? If `ClientCtrl` starts the modal, it should get a promise with the modal result. Can you use that result to update `$scope.opportunities` in `ClientCtrl` – hansmaad Jul 02 '15 at 15:01

1 Answers1

0

If I understand your question correctly, you should be using promises instead of $watch.

Service

getOpportunities: function(id) {

    // $http.get returns a promise itself.
    // With the $q object you can write more complex code if needed
    var deferred = $q.defer();
        $http.get("/what/ever")
        .success(function(data) { 
            deferred.resolve(data);
        })
        .error(function() {
            deferred.reject("Oops");
        });
    return deferred.promise;
}

Controller

var promise = opportunityService.getOpportunities($scope.id);
promise.then(
    function(p) { 
        $scope.opportunities = p.data;
    },
    function(data) {
        alert("error");
    });
};
Ricardo Velhote
  • 4,630
  • 1
  • 24
  • 30