1

I have an Ionic app that makes use of a sidebar. In this sidebar there is the functionality to refresh your data which goes off to the servers and returns a new JSON object that I save to the local storage.

The problem that I'm facing here is that when you open up the sidemenu and hit the 'Refresh My Data' menu item, the data does indeed get returned and saved locally successfully but I also need to refresh or re-run the controller of whichever view/state I'm on, so that the current view can make use of the new data that is in storage.

My index.html:

 <ion-side-menu side="left" ng-controller="sidebarController"> <ion-header-bar class="bar-positive"> <h1 class="title">Menu</h1> </ion-header-bar> <div class="list has-header"> <div class="item item-icon-left" ng-click="refreshData()"><i class="icon ion-refresh"></i> Refresh My Data</div> </div> </ion-side-menu> <ion-side-menu-content> <ion-nav-view></ion-nav-view> </ion-side-menu-content> </ion-side-menus> 

As you can see the sidebar has it's own dedicated controller called sidebarController which you can see here:

app.controller('sidebarController', ['$scope', '$ionicSideMenuDelegate', '$storage', '$registerService', '$ionicLoading', '$ionicPopup', function($scope, $ionicSideMenuDelegate, $storage, $registerService, $ionicLoading, $ionicPopup) { $scope.refreshData = function () { // Display loading modal $ionicLoading.show({ template: 'Syncing with server...' }); // Call the getMemberDetails service var memberNo = $storage.get('memberNo', ''); $registerService.getMemberDetails(memberNo). success(function(data, status, headers, config) { // Store details to local storage $storage.setObject('member', data.member); // Close loading modal and sidebar $ionicLoading.hide(); closeSidebar(); // Display success message var alertPopup = $ionicPopup.alert({ title: 'Success', template: 'Your data hsa been successfully sycned.' }); }). error(function(data, status, headers, config) { $ionicLoading.hide(); var alertPopup = $ionicPopup.alert({ title: 'Oops', template: 'An error occured while trying to sync with our servers. Please make sure you have a data connection.' }); // Close the sidebar closeSidebar(); }); } function closeSidebar () { if ($ionicSideMenuDelegate.isOpenLeft()) { $ionicSideMenuDelegate.toggleLeft(); } } } ]); 

So basically after refreshData () has run, I need to find out which state or view I'm currently in, and then re-run the controller for that view. Is there a simple way of doing this?

1
  • controllers are not "re-run". if you want to update a view based on a change that the view doesn't know about, you need to use $broadcast or $emit, or reload the view entirely. Commented Oct 27, 2015 at 10:59

3 Answers 3

1

You have two options here:

  1. broadcast an event from your sidebarController after the data has been successfully synced and add logic to the controllers to listen for that event and update the model/view.
  2. Store your data (members) in a service and make the different controllers work with the same reference to the data. Angular will then take care of refreshing the views with its change detection.

I'd go for option two. Since you centralize the logic on how to load the data in a service which is responsible for fetching data. The controllers only work with the data return by the service. Plus you only have to do one request to the server when refreshing data.

Example of a service:

angular.facorty('Member', function($http) { var items = []; return { items: items, refresh: function() { items.length = 0; // clear the items return $http .get(...) .then(function(res) { angular.forEach(res.data, function(item) { items.push(item); }); }); } } }) .controller('sidemenuController', function(Member) { // show loading here Member.refresh().finally( /* hide loading */) }) .controller('MembersController', function($scope, Member) { $scope.members = Member.items; Member.refresh(); // additionally show some loading indication });

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

3 Comments

Depending on your app, yes. I updated the answer with the "why".
Just a quick question though.. So say I go with option 2, all my controllers/views access the data from a central point - and that's great. But after I update the data in my service, would that then automatically refresh/update the views with the new data as well? I hope it makes sense what I"m saying...
Yes, as long as you always return the same reference to the data array in the service.
0

AngularJS tracks your changes to $scope when you are running js, except for two (might be more, but two main) scenarios:
1. When a code is called in a timely fashion (e.g. by setTimeout()).
2. When a code is run by an event (angular can't predict).

In those two scenarios, you should use $scope.apply(); to trigger Angular's "magic engine" :)

naive example:

function myJsonUpdated(jsonData){ $scope.apply(function(){ $scope.myscopeData... = jsonData... }); } 

this site might help: AngularJS $watch() , $digest() and $apply() tutorial

Side Note: you can use $scope.digest() instead, but apply is better practice in my opinion.

Comments

0

Try calling $route.reload() from the controller.

Comments