Anguna Anguna - 3 months ago 7
AngularJS Question

How to get dynamic view to update properly when scope variable changes

I am developing an Angular SPA and on one view there is a

$scope
variable that determines the majority of the content for that page. If the user clicks on a different link in a menu, the parameters will be passed through the url, and the scope variable gets updated. However, when doing this, the view does not get updated. I generally don't ask questions on here, but I have tried what seems like everything, and can't figure out why the view isn't being updated. Here is what the code looks like:

html

<div ng-init="loadTopicView()">
<h1 ng-bind="selectedTopic.title"></h1>
<p ng-bind="selectedTopic.body"></p>
</div>


js

$scope.loadTopicView = function() {
var selectedTopic = urlParams.index;
$scope.selectedTopic = $scope.topics[selectedTopic];
}


Initially, I thought because of the way it was being called the
$scope.selectedTopic
wasn't getting the correct value, like the url didn't have the value yet.
$scope.topics
is an array of objects and which ever link the user clicks on will pass an index through the url and then assign the correct object to the
$scope.selectedTopic
.

After trying many things, I even tried running it over and over to see if it would make a difference using
window.setInterval
but it didn't change the fact that for some reason the html isn't updating.

I've seen issues like this before, with boolean values and ng-show but I can't figure this one out. Any help would be deeply appreciated.

More Info as requested:

Here is the html for the side nav that selects what content will be showed on the page

<ul class="sidebar-nav">
<li ng-repeat="topic in topics">
<a href="" ng-click="loadPage('/topics', topic.id)" ng-bind="topic.title"></a>
</li>
</ul>


Here is the javascript for
$scope.loadPage


$scope.loadPage = function(path, passedParams) {
// at this point, `path` is going to the /topics view, and the `passedParams` has the id for the topic to load, lets say it is the integer: 5.

if(path === $location.path() && path == '/topics') { // If you're switching topics but staying on the topic page
if (!passedParams) {
$state.reload(); // Meaning just refresh the page, no topic was selected.
} else {
$location.path(path).search({params: passedParams});
$rootScope.$emit("CallingTopicUpdate", {});
}
} else { // This works fine in loading the correct topic, it is only when you are already on the topic page (so the above if), that it won't load the scope changes.
if (passedParams) {
$location.path(path).search({params: passedParams});
} else {
$location.path(path);
}
}
};


oh and this is in the same controller as the
$scope.loadTopicView


$rootScope.$on("CallingTopicUpdate", function(){
$scope.loadTopicView();
});


Using
$emit
and
$on
so that when a different topic is selected while on the topic page, it will run this function again. But this is where, it updates the
$scope.selectedTopic
but the change isn't made manifest in the data that is loaded on the screen.


As a result, you can see the params (an integer representing a topic), change in the url, but the page view that is dynamically binding data depending on the topic doesn't switch to the item you selected until you select another topic. In essence, if you keep selecting topics, the url is right, and the view is one topic behind the url.

Answer
$scope.loadTopicView = function(param) {
          var selectedTopic  = param ? param : 1;
          $scope.selectedTopic = $scope.topics.filter(function(value){return value.id==selectedTopic; });
};
$scope.loadPage = function(path, passedParams) {
              // at this point, `path` is going to the /topics view, and the `passedParams` has the id for the topic to load, lets say it is the integer: 5.
              if(path === $location.path() && path == '/topics') { // If you're switching topics but staying on the topic page
                  if (!passedParams) {
                      $state.reload(); // Meaning just refresh the page, no topic was selected.
                  } else {
                      $location.path(path).search({params: passedParams}); 
                      $rootScope.$emit("CallingTopicUpdate", passedParams);
                  }
              } else { // This works fine in loading the correct topic, it is only when you are already on the topic page (so the above if), that it won't load the scope changes.
                  if (passedParams) {
                      $location.path(path).search({params: passedParams});
                  } else {
                      $location.path(path);
                  }
              }
};
$rootScope.$on("CallingTopicUpdate", function(event, param){
            $scope.loadTopicView(param);
});
Comments