1
votes

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;

}]);
3
When route is changed, Associated controller initialized every time. Can you please show me the code of HomeController So i can help you on that, - Mohan Singh
I have added the info Mohan. - Finnjon
Important part is : If you are already on '/' this url and you are trying to click on '/' the same routes. In this case controller is not going to initialized . To achieve this write some function and broadcast an event. and listen that event in HomeController. Let me know if i am on the same page So i can write plunker or jsfiddle for you - Mohan Singh
Actually that's not the problem. The problem is when I go from '/' to '/discover' and do some stuff, the data doesn't get updated. - Finnjon
Do you mean that you are updating $scope.somevariable in discover views and expecting that to be updated in the Home view. ? - Mohan Singh

3 Answers

2
votes

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

1
votes

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});
}
0
votes

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.