332

I'm using Angular UI Router and would like to reload the current state and refresh all data / re-run the controllers for the current state and it's parent.

I have 3 state levels: directory.organisations.details

directory.organisations contains a table with a list of organisations. Clicking on an item in the table loads directory.organisations.details with $StateParams passing the ID of the item. So in the details state I load the details for this item, edit them and then save data. All fine so far.

Now I need to reload this state and refresh all the data.

I have tried:

 $state.transitionTo('directory.organisations');

Which goes to the parent state but doesn't reload the controller, I guess because the path hasn't changed. Ideally I just want to stay in the directory.organisations.details state and refresh all data in the parent too.

I have also tried:

$state.reload()

I have seen this on the API WIKI for $state.reload "(bug with controllers reinstantiating right now, fixing soon)."

Any help would be appreciated?

Flip
  • 6,233
  • 7
  • 46
  • 75
Holland Risley
  • 6,969
  • 9
  • 25
  • 34

18 Answers18

575

I found this to be the shortest working way to refresh with ui-router:

$state.go($state.current, {}, {reload: true}); //second parameter is for $stateParams

Update for newer versions:

$state.reload();

Which is an alias for:

$state.transitionTo($state.current, $stateParams, { 
  reload: true, inherit: false, notify: true
});

Documentation: https://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state#methods_reload

Rohan
  • 8,006
  • 5
  • 24
  • 32
  • 21
    Probably worth noting that none of these actually reload the page as well. If you want to reload the state AND the page, there is no `ui-router` method for it I think. Do `window.location.reload(true)`. – SimplGy Jun 19 '14 at 23:53
  • 15
    @SimpleAsCouldBe if you wanted to be more angular about it you could do `$window.location.reload();`. Although this seems a little overkill it could make testing/mocking/knowing all dependencies a piece of code has things a little easier. – edhedges Nov 05 '14 at 19:24
  • @ManojG It can go in any controller whether it's a child or a parent of the current scope. If you were to create a refresh button, attach a ng-click handler to a new function inside a controller with the answer's code inside it. – Rohan Feb 21 '15 at 12:33
  • 1
    Just curious, what exactly is "$state.current" means? I can't see clear explanations on ui-router's API, any help will be appreciated, thanks! – user2499325 May 29 '15 at 06:32
  • Does not work for me, second solution with transitionTo works for me. – Andi Giga Oct 20 '15 at 16:53
  • 3
    @user2499325 : $state.current returns an object with all the data you have in you stateProvider : ``` { url: "/place/:placeId", controller: "NewPlaceController", controllerAs: "placeVM", templateUrl: "places/new.place/new.place.details.html", name: "index.places.placeDetails" } ``` – Xavier Haniquaut Nov 06 '15 at 14:11
  • 2
    You can replace {} with $stateParams if you already have parameters loaded as such: $state.go($state.current, $stateParams, {reload: true}); – Taku Jan 29 '16 at 06:50
  • I am doing as mentioned above but it adds some junk value in the URL of the browser like this "$$uirouterextrasreload=0.7203978995615361" and I want to eliminate it – Shubham Tiwari Sep 15 '16 at 06:25
154

This solution works in AngularJS V.1.2.2:

$state.transitionTo($state.current, $stateParams, {
    reload: true,
    inherit: false,
    notify: true
});
Rusty Fausak
  • 7,355
  • 1
  • 27
  • 38
Holland Risley
  • 6,969
  • 9
  • 25
  • 34
68

That would be the final solution. (inspired by @Hollan_Risley's post)

'use strict';

angular.module('app')

.config(function($provide) {
    $provide.decorator('$state', function($delegate, $stateParams) {
        $delegate.forceReload = function() {
            return $delegate.go($delegate.current, $stateParams, {
                reload: true,
                inherit: false,
                notify: true
            });
        };
        return $delegate;
    });
});

Now, whenever you need to reload, simply call:

$state.forceReload();
M K
  • 9,138
  • 7
  • 43
  • 44
  • 6
    inifinit loop of death – C. S. Sep 07 '14 at 23:44
  • 6
    Sounds like you have an interceptor somewhere that gets triggered. I've tested this solution several times and it works fine. – M K Sep 08 '14 at 07:55
  • 2
    @MK Thank you for that note. It steered me towards the solution of my own, different problem. I've spent hours trying to find out why my requests were getting doubled, then tripled etc. and it was all because of an interceptor (https://github.com/witoldsz/angular-http-auth). – Maciej Gurban Dec 10 '14 at 15:42
57

for ionic framework

$state.transitionTo($state.current, $state.$current.params, { reload: true, inherit: true, notify: true });//reload

$stateProvider.
  state('home', {
    url: '/',
    cache: false, //required

https://github.com/angular-ui/ui-router/issues/582

RouR
  • 6,136
  • 3
  • 34
  • 25
  • Works fine for me where `$state.go` failed to redirect to a fresh state. Thanks @RouR. Saved my day. – Guillaume Wuip Aug 06 '15 at 06:04
  • I think replace $state.go with $state.transitionTo. So wherever you were calling $state.go, just replace that. It could look something like $state.transitionTo('tab-name', {key: value},{ reload: true, inherit: true, notify: true } – Bill Pope Nov 13 '15 at 14:53
  • 2
    cache: false does the trick.. but how much does it effect performance? – FrEaKmAn Jan 11 '16 at 08:43
  • change $state.go with $state.transitionTo to change state and reload @ManojG – Gery Jan 28 '16 at 11:31
  • Do I have to include some new library to use `$state`? I am running ionic 1.4.0, angular 1.5.3 – josinalvo Apr 13 '17 at 15:40
  • adding `cache: false` reloads even directive, you saved my day thx. – khashashin Jan 23 '19 at 08:20
45

Probably the cleaner approach would be the following :

<a data-ui-sref="directory.organisations.details" data-ui-sref-opts="{reload: true}">Details State</a>

We can reload the state from the HTML only.

Vaibhav Pachauri
  • 2,671
  • 2
  • 19
  • 32
  • 7
    You can also use ui-sref-opts="{reload: 'child.state'}" to avoid reloading the whole page, where 'child.state' is a string representing your actual state. – Michael Fulton Mar 24 '16 at 21:13
22

@Holland Risley 's answer is now available as an api in latest ui-router.

$state.reload();

A method that force reloads the current state. All resolves are re-resolved, controllers reinstantiated, and events re-fired.

http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state

Jefftopia
  • 2,105
  • 1
  • 26
  • 45
Muthukannan Kanniappan
  • 2,080
  • 1
  • 16
  • 18
16
$state.go($state.current, $stateParams, {reload: true, inherit: false});
WiredIn
  • 4,157
  • 4
  • 27
  • 23
Weston Ganger
  • 6,324
  • 4
  • 41
  • 39
14
$scope.reloadstat = function () { $state.go($state.current, {}, {reload: true}); };
Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
user7961355
  • 141
  • 1
  • 2
7

if you want to reload your entire page, like it seems, just inject $window into your controller and then call

$window.location.href = '/';

but if you only want to reload your current view, inject $scope, $state and $stateParams (the latter just in case you need to have some parameters change in this upcoming reload, something like your page number), then call this within any controller method:

$stateParams.page = 1;
$state.reload();

AngularJS v1.3.15 angular-ui-router v0.2.15

MarcoSantana
  • 739
  • 10
  • 10
6

Silly workaround that always works.

$state.go("otherState").then(function(){
     $state.go("wantedState")
});
Fanchi
  • 757
  • 8
  • 23
3

For angular v1.2.26, none of the above works. An ng-click that calls the above methods will have to be clicked twice in order to make the state reload.

So I ended up emulating 2 clicks using $timeout.

$provide.decorator('$state',
        ["$delegate", "$stateParams", '$timeout', function ($delegate, $stateParams, $timeout) {
            $delegate.forceReload = function () {
                var reload = function () {
                    $delegate.transitionTo($delegate.current, angular.copy($stateParams), {
                        reload: true,
                        inherit: true,
                        notify: true
                    })
                };
                reload();
                $timeout(reload, 100);
            };
            return $delegate;
        }]);
thanos panousis
  • 464
  • 6
  • 17
  • Navigation.reload() required two clicks with Angular 1.3.0-rc0, but the transitionTo() worked fine. Maybe try upgrading if you have this issue – sricks Apr 09 '15 at 16:24
3

Everything failed for me. Only thing that worked...is adding cache-view="false" into the view which I want to reload when going to it.

from this issue https://github.com/angular-ui/ui-router/issues/582

Hans
  • 995
  • 8
  • 11
3

Not sure why none of these seemed to work for me; the one that finally did it was:

$state.reload($state.current.name);

This was with Angular 1.4.0

BarrySW19
  • 3,759
  • 12
  • 26
2

I had multiple nested views and the goal was to reload only one with content. I tried different approaches but the only thing that worked for me is:

//to reload
$stateParams.reload = !$stateParams.reload; //flip value of reload param
$state.go($state.current, $stateParams);

//state config
$stateProvider
  .state('app.dashboard', {
    url: '/',
    templateUrl: 'app/components/dashboard/dashboard.tmpl.html',
    controller: 'DashboardController',
    controllerAs: 'vm',
    params: {reload: false} //add reload param to a view you want to reload
  });

In this case only needed view would be reloaded and caching would still work.

Dmitriy Nevzorov
  • 6,042
  • 1
  • 20
  • 28
2

I know there have been a bunch of answers but the best way I have found to do this without causing a full page refresh is to create a dummy parameter on the route that I want to refresh and then when I call the route I pass in a random number to the dummy paramter.

            .state("coverage.check.response", {
                params: { coverageResponse: null, coverageResponseId: 0, updater: 1 },
                views: {
                    "coverageResponse": {
                        templateUrl: "/Scripts/app/coverage/templates/coverageResponse.html",
                        controller: "coverageResponseController",
                        controllerAs: "vm"
                    }
                }
            })

and then the call to that route

$state.go("coverage.check.response", { coverageResponse: coverage, updater: Math.floor(Math.random() * 100000) + 1 });

Works like a charm and handles the resolves.

ewahner
  • 1,149
  • 2
  • 11
  • 23
2

You can use @Rohan answer https://stackoverflow.com/a/23609343/3297761

But if you want to make each controller reaload after a view change you can use

myApp.config(function($ionicConfigProvider) { $ionicConfigProvider.views.maxCache(0); ... }
Community
  • 1
  • 1
EduLopez
  • 721
  • 7
  • 18
2

If you are using ionic v1, the above solution won't work since ionic has enabled template caching as part of $ionicConfigProvider.

Work around for that is a bit hacky - you have to set cache to 0 in ionic.angular.js file:

$ionicConfigProvider.views.maxCache(0);
Maksood
  • 1,180
  • 14
  • 19
1

I had this problem it was wrecking my head, my routing is read from a JSON file and then fed into a directive. I could click on a ui-state but I couldn't reload the page. So a collegue of mine showed me a nice little trick for it.

  1. Get your Data
  2. In your apps config create a loading state
  3. Save the state you want to go to in the rootscope.
  4. Set your location to "/loading" in your app.run
  5. In the loading controller resolve the routing promise and then set the location to your intended target.

This worked for me.

Hope it helps

Evan Burbidge
  • 827
  • 9
  • 16