Finnjon
Finnjon

Reputation: 671

How to get my angular controller to reload data

I have an angular app with three views. When it loads it runs some code to populate the $scope variables. When I change views and then go back to the controller I want the initial code to run again but it doesn't. It seems it is cached and the $scope variables are not updated based on what happened.

How can I force the controller to run the initialisation code every time the view is loaded?

My routes:

app.config(function ($routeProvider) {
  $routeProvider
    .when('/', {
        controller: 'HomeController',
        templateUrl: 'home.html'
    })
    .when('/teach', {
      controller: 'TeachController',
      templateUrl: 'teach.html'
    })
    .otherwise({
        redirectTo: '/'
    });
});

The code I want to run every time the '/' route is clicked:

getSubPools.success(function(data) {
  $scope.userPools = data;
});

Controller in full:

app.controller('HomeController', ['$scope', '$filter', 'stream', 'removeDroplet', 'qrecords', 'helps', 'get_user', 'updateRecords', 'getSubPools', function($scope, $filter, stream, removeDroplet, qrecords, helps, get_user, updateRecords, getSubPools) {

  get_user.success(function(data) { //get current user
    $scope.user = data;
  });

  getSubPools.success(function(data) {
    $scope.userPools = data;
  });

  stream.success(function(data) {
    $scope.stream = data;
    if ($scope.stream.length === 0) { //determine if user has stream
      $scope.noStream = true;
    } else {
      $scope.noStream = false;
    }
    $scope.getNumberReady(); //determine if any droplets are ready
    if ($scope.numberReady === 0){
      $scope.noneReady = true;
    } else {
      $scope.noneReady = false;
      $scope.stream = $filter('orderBy')($scope.stream, 'next_ready'); //orders droplets by next ready
    }
  });

    $scope.showEditStream = true;
    $scope.showStream = false;
    $scope.rightAnswer = false;
    $scope.wrongAnswer = true;
    $scope.noneReady = false;
    $scope.subbedDroplets = [];
    $scope.focusInput = false;

}]);

Upvotes: 1

Views: 940

Answers (3)

Finnjon
Finnjon

Reputation: 671

The issue here was that on clicking the link to '/' not all of the initialisation code was rerunning. Rather than making calls to the database to get fresh data, angular was just returning old data. The way I fixed this was to rewrite my factories. The factories that were failing were written:

app.factory('stream', ['$http', function($http) {
  return $http.get('/stream/')
  .success(function(data) {
    return data;
  })
  .error(function(err) {
    return err;
  });
}]);

The factory that worked every time was written:

app.factory('stream', ['$http', function($http) {
  return {
    fetch: function () {
      return $http.get('/stream/');
    }
  }
}]);

Now it runs every time. I am not sure why though.

Upvotes: 0

Doron Sinai
Doron Sinai

Reputation: 1186

You can use the $routeChangeStart and $routeChangeSuccess events to reload the data into the controller:

https://docs.angularjs.org/api/ngRoute/service/$route

Edit: As mohan said as this will work for every route change, you can make a service to catch these events and for each route broadcast a special event.

And in the relevant controller/service listen to this event and reload data

Upvotes: 2

Santhakumar P
Santhakumar P

Reputation: 51

If you want to force reload, then add an click function like follows,

Note: This will work only if you use $stateProvider

<a href="" ng-click="goToHome()">Home</a>

and in controller ,

$scope.goToHome = function(){
    $state.transitionTo('home', {}, {reload:true});
}

Upvotes: 1

Related Questions