2

Please help! I am pulling my hair out over this. I've tried a lot of tutorials for this and can't seem to get anything to work even remotely.

Users can add/delete/update user information on a page, and I want it to refresh whenever they do one of those actions. All of the actions write to the DB just fine and I have had various success with getting the values back out, but I cannot get the view to update in real-time.

I can't use $scope.$apply(); $digest already in process. I feel like there is just some major key I'm missing.

Service

angular.module('userlistFactory', [])
    .service('Data', function($http){
        this.list = function(){
            return $http.get('.../getUsers.php', {cache: true})  
            .then(function(data){
                return data.data;
            });
        }

Controller

userlistControllers.controller('UserListCtrl', ['$scope', 'Data', function ($scope, Data){

  Data.list().then(function (data) {   // Populates the page the first time through
    $scope.users = data;
  })

  $scope.$watch('Data.list()', function(newValue){  // At this point, I don't understand
    $scope.users = newValue;
  }, true);

View

<tr ng-repeat-start="user in users| filter:query | orderBy:'id'">
    <td><a href="#/profile/{{user.id}}">{{user.id}}</a></td>
    <td>{{user.firstname}}</td>  // etc...

Thanks for reading.

2
  • Whats the use of $scope.$watch('Data.list()'? How do you know that data is inserted/updated? Commented May 22, 2015 at 22:31
  • Are your add/update/delete functions also in the service? It seems like if your list function is working you could just do something like Data.add(item).then(function() { Data.list(); } ) in the controller. Your watch is not going to keep the list refreshed. Commented May 22, 2015 at 22:51

1 Answer 1

2

As you are returning your $http object and setting the call back in the scope, there is no need to handle a callback in your service unless you wanted to handle the .fail() or had further processing. It could even be the return that is causing errors.

angular.module('userlistFactory', [])
.service('Data', function($http){
    this.list = function(){
        return $http.get('.../getUsers.php', {cache: true});
        }
    });

Your call to get the users then would look ok but it will only run once. If you want to call it to update after DB changes, you will need to put it in to a method

    function UpdateUsers(){         
      Data.list().then(function (data) {
         $scope.users = data;
         $scope.$apply();  //Because it was asynch
      });
    }

You can get rid of the $watch section.

Now, when your user adds, deletes, etc., you just call your update Users method and the a synch request will be started. When it returns, $scope.users will be updated and the $scope.$apply() will call the digest cycle updating your page.

Of course you want your list to update immediately as you even had in comments. To do this, just call the method in your controller.

    UpdateUsers();

It might seem a little confusing about the $http object. You are returning the object and by adding .then(.... you are registering your call back. Most of the code examples show it all at once $http(...).then(...) but in your case, you are creating it in your service and returning the object where you then register your call back on your controller. $http ----> back to controller add .then(..) so you do not need to handle it in both places. You can how ever handle the .fail(... anyplace you would like as well if you needed to handle that.

To eliminate some confusion about the $watch. Angular only cares about things when they are bound. If I have a value that is not being used anywhere but I want to do something if it changes, I would need to then $watch it for a change. That is because there is no event or anything to trigger the code. Adding the $watch is done automatically when you bind it to something because it then $watches for it in the digest cycle so it can update whatever it needs to update.

Sign up to request clarification or add additional context in comments.

1 Comment

In the end I decided to have my API return the full list of users for any add/delete/update action. This is how I had to format those actions: $scope.updateUser = function(user) { Data.update(user).then(function(data){ $scope.users = data.data; }) } I'll give you the answer because it got me to think about the problem differently. Thanks!

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.