11

In my angular project, when changing the path with $location.path('/foobar') the destination view is displayed but the data aren't reloaded (typically after saving an item and going back to the list, the list is not updated).

I tried to add $route.reload() or $scope.apply(), but nothing change.

I don't know what's wrong or missing to make this work.

UPDATE

  • $location.url() doesnt' work either
  • I'm using angular 1.2.26

UPDATE 2 - ANSWER

Ok, after a lot of comments and answers, I think it's time to end this.
I didn't think it would have been a so complicated question.

So, my conclusion, giving all you said is :

  • Giving simple example of @yvesmancera, the default behavior of the controller is to reload itself
  • In a complex controller with a resource factory and some REST calls, any save or update action should also manually update the list reference, or trigger a full reload of the list

All of you gave me some good advices, so thank you.

Sylver
  • 2,285
  • 3
  • 29
  • 40
  • Use $location.url('/foobar') instead. See http://stackoverflow.com/questions/24794115/using-window-or-location-to-redirect-in-angularjs-resolved – csbarnes Jun 25 '15 at 18:25
  • nope, same problem with $location.url(), data aren't reloaded – Sylver Jun 25 '15 at 18:36
  • I'm not sure to understand your question. afaik the controller is linked to the view, via the routeProvider, so i supposed it is called, else the view wouldn't have data, or did i miss something? – Sylver Jun 25 '15 at 18:46
  • Are you saying the list is shown but the data is not updated with the newly saved item? – Kathir Jun 25 '15 at 18:48
  • the /foobar ,does the controller make any ajax calls to the server for this page? – Kathir Jun 25 '15 at 18:50
  • Can you post code relevant to how you are saving the list/item? Reloading the page is overkill and sort of defeats the purpose of using angular. – csbarnes Jun 25 '15 at 18:51
  • You got to fetch the list again after you save an item? How are you fetching the list? – Sudhansu Choudhary Jun 25 '15 at 18:54
  • Ok, so my problem is that i need to trigger a reload of the list when i'm calling back my list view. I supposed it was something automatic. – Sylver Jun 25 '15 at 19:01
  • 1
    ng-model should handle a lot of this for you. Your save should commit your changes and update your model. Reloading the page is probably not needed. Chances are your data is loaded when your controller starts, and the controller simply maintains the old data since it never goes out of scope. – Roman K. Jun 26 '15 at 14:02
  • 1
    @RomanK. that's what I meant! I didn't mean to reload the page, when I said refresh the list. You are right, the save method should update the model. Sylver, I could only post some pseudo code as I don't have idea about your implementation of data models, but I've tried explaining what I meant by refreshing the list fetch in my answer. – Sudhansu Choudhary Jun 26 '15 at 18:34
  • [This answer works too](https://stackoverflow.com/a/17459771/3180309) `$location.url($location.path());` – jmbmage Mar 15 '19 at 20:34

6 Answers6

8

Use $window.location.href. to reload the page. I just check on $location document:

Page reload navigation

The $location service allows you to change only the URL; it does not allow you to reload the page. When you need to change the URL and reload the page or navigate to a different page, please use a lower level API, $window.location.href.

Example:

$window.location.href = "/your/path/here";
Community
  • 1
  • 1
Huy Nguyen
  • 2,025
  • 3
  • 25
  • 37
  • 3
    There is a problem. Yes $window.location.href will reload the page only if path is different from the current one. In AngularJS usually path is not changed, but only the part after anchor (#). So if staying on /#/some-route-1, calling $window.location.href = "/#/some-route-2" will not trigger page reload. – Ross Jan 23 '18 at 09:07
3

I had the same problem just yesterday, if you try to navigate to the same path you're already in, angular won't try to reload the view and controller. What fixed it for me is appending a "/" at the end of each route in $routeProvider, e.g:

$routeProvider
  .when('/', {
    templateUrl: 'views/home.html',
    controller: 'HomeCtrl'
  })
  .when('/About/', {
    templateUrl: 'views/about.html',
    controller: 'AboutCtrl'
  })
  .when('/Contact/', {
    templateUrl: 'views/contact.html',
    controller: 'ContactCtrl'
  })

Edit

Here is a working plunkr with angular 1.2.26

http://plnkr.co/edit/jkGKKCp0djN6Jvy2fIRd?p=preview

yvesmancera
  • 2,915
  • 5
  • 24
  • 33
  • I tried your solution, but it doesn't change anything for me. Maybe different angular version, i will update the post about that. – Sylver Jun 25 '15 at 20:49
  • I updated my answer and added a plunkr, I got it to work with Angular 1.2.26, hope it helps. – yvesmancera Jun 26 '15 at 17:51
  • Thanks for your example. In your solution you were mentioning to append a "/" at the end of the route to reload the controller, else it wouldn't reload. But if i'm trying your plunkr example with and without a "/" at the end of paths, it always works. So, giving this working simple example here, I suppose that's the default behavior, and something in my project is preventing it to happen. Sounds right? – Sylver Jun 26 '15 at 22:05
  • That did it! thks! – simon Jan 18 '17 at 11:20
2

Pseudo Code:-

    app.controller('myController', ['$scope', '$location','$http', 'ItemListService'
                    function($scope, $location, $http, ItemListService){
       $scope.data = function(){
       ItemListService.getAllItems(); //get all the items;
    };
        $scope.saveMethod = function(item){
       $scope.data = ItemListService.save(item); //this is the refresh part, return data through save method. Pull the latest data and bind it to the scope.
         $location.path('/fooView'); //dont think you even need this if you are entering data in a modal sorta thing, which on the same view. 
    }
    }]);

You service should look like,

app.service('ItemListService', function(){
    this.getAllItems = function(){
      //get the items from itemList
     //return all the items
   }

  this.save = function(item){
     //save the item in itemList
     //**return all items again, call getAllItems here too.
}
});

Hope this helps!!

Sudhansu Choudhary
  • 3,322
  • 3
  • 19
  • 30
  • This answer is the closest to what i decided to do, so i'm accepting it. But all other propositions are right too. – Sylver Jun 26 '15 at 22:50
1

You can switch https://github.com/angular-ui/ui-router it has method $state.reload() which can re-initialize whole controller.

If you dont want to switch ther is problem that controller is still living but you can implement after save

$rootScope.$broadcast('data:updated', $scope.data);

then wrap method of loading data in controller to function and then you can push new data to existing list / or make ajax reload

$rootScope.$on('data:updated',function(listener,data) {
 $scope.data.push(data);
});

$rootScope.$on('data:updated',function()
{
   callAjax.then(function(data) {
     $scope.data = data;
   }
});

https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$on

Milos Mosovsky
  • 2,913
  • 1
  • 16
  • 18
0

Try $scope.dataModel.$save(); $location.url('/foobar');
Another reason might solve the problem is: when you redirect to /foobar, the controller of foobar should have a AJAX call to your server to load the new data. And you should use angular factory to make your AJAX calls.
If it is still not working, can you give more information about the version of the angular you are using, as well as your backend framework and database.

Shaohao
  • 3,471
  • 7
  • 26
  • 45
  • The $location.url/path is triggered inside a $save(). I'm using angular $resource and using factory to define my model objects. – Sylver Jun 25 '15 at 20:54
0
$location.path("/login");
$timeout(() => $scope.$apply(), 1000);

works for me

Yevhenii Bahmutskyi
  • 1,561
  • 3
  • 20
  • 38