New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$state.reload() should reinitialize the controller #582

Closed
ghengeveld opened this Issue Nov 14, 2013 · 170 comments

Comments

Projects
None yet
@ghengeveld

ghengeveld commented Nov 14, 2013

As discussed in #76, $state.reload() does reload the resolves, but doesn't reinitialize the controller with the newly resolved values. Since the whole point of reloading the resolves is to refresh the scope with the new data, reinitializing the controller is a requirement for $state.reload() to be of any use.

Demo: http://plnkr.co/edit/GNr1bN?p=preview

@mfield

This comment has been minimized.

mfield commented Nov 14, 2013

I don't know whether this behavior is intentional or not. In my application, I skirted this issue by setting a $watch on the values in $state like http://plnkr.co/edit/DVFG8T?p=preview

@ghengeveld

This comment has been minimized.

ghengeveld commented Nov 15, 2013

Good to see there is a workaround. Still, it does make sense to reload the controller too so it resets it's state. Besides, using $state.$current.locals.globals circumvents the DI syntax for resolved properties, which makes it a lot less explicit (and explicit DI is what makes it so nice and simple).

@laurelnaiad

This comment has been minimized.

laurelnaiad commented Nov 15, 2013

I haven't checked but if reload induces stateChangeSuccess then that would be better than watching if you're watching just so you can track reload-based changes.

@tamtakoe

This comment has been minimized.

tamtakoe commented Nov 18, 2013

👍

@panga

This comment has been minimized.

panga commented Dec 2, 2013

I agree with @ghengeveld, $state.reload() also should reinitialize the controllers to refresh scope.

@nateabele

This comment has been minimized.

Member

nateabele commented Dec 2, 2013

Yup, agreed, sorry for overlooking that. It'll get fixed as soon as I have time.

@lc-nyovchev

This comment has been minimized.

lc-nyovchev commented Jan 14, 2014

👍

@johnculviner

This comment has been minimized.

johnculviner commented Jan 17, 2014

👍 Anyone know another workaround for this? I'm building out a massive SPA and I need each of the controllers (all different routes) to refresh when the user changes a drop down that is part of the surrounding chrome of the SPA. Right now it looks like I have to write a bunch of code in each controller which is going to be bad. Thanks!

@appglu-devinpoolman

This comment has been minimized.

appglu-devinpoolman commented Jan 17, 2014

Have you tried flipping the reload flag on transitionTo?

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

This comment has been minimized.

johnculviner commented Jan 17, 2014

Thanks for the thought. I gave it a shot but to no avail...

I even tried changing:

  function shouldTriggerReload(to, from, locals, options) {
    if ( to === from && ((locals === from.locals) || (to.self.reloadOnSearch === false)) ) {
      return true;
    }
  }

To:

function shouldTriggerReload(to, from, locals, options) {

    if(options.reload) {
        return true;
    }

    if ( to === from && ((locals === from.locals) || (to.self.reloadOnSearch === false)) ) {
      return true;
    }
  }

Because it was returning false when options.reload == true (which didn't make sense to me) but that didn't work either. Bummer! I'm gonna have to put watches on a broadcast for that "global drop down change" I guess until this is resolved or I can figure it out on my own time. UI Router is AMAZING otherwise though. I recommend it over the built in Angular one whenever I talk or present on Angular!

@zakjan

This comment has been minimized.

zakjan commented Jan 28, 2014

What is state of this bug?

@nateabele

This comment has been minimized.

Member

nateabele commented Jan 28, 2014

@zakjan Hope to have a fix pushed by this weekend.

@johnculviner

This comment has been minimized.

johnculviner commented Jan 29, 2014

👍 Sweet, pumped for this as it should clean up the code on a few of my pages quite significantly. Thanks!

@zakjan

This comment has been minimized.

zakjan commented Jan 31, 2014

👍 looking forward to it

@sausaw

This comment has been minimized.

sausaw commented Feb 4, 2014

👍

@marccantwell

This comment has been minimized.

marccantwell commented Feb 5, 2014

@nateabele any updates?

@PeterMajer

This comment has been minimized.

PeterMajer commented Feb 12, 2014

I'm using some transition state as a workaround:

state('transition', {
  url: 'transition?destination',
  controller: function ($state, $stateParams) {
    $state.go($stateParams.destination);
  }
})

And then:

//state won't reload
$state.go('new-state');
//temporary workaround to ensure reload
$state.go('transition', {destination: 'new-state'});
@aphexddb

This comment has been minimized.

aphexddb commented Feb 12, 2014

@PeterMajer great hack, i was using

$state.transitionTo('new-state', null, {'reload':true});
@zakjan

This comment has been minimized.

zakjan commented Feb 13, 2014

Any of those workarounds don't reinitialize controller for me.

@rohitranjan1991

This comment has been minimized.

rohitranjan1991 commented Feb 19, 2014

one workaround is recreate the view by toggling the value of ng-if provided u have the controller defined inside the ng-if div or on it

@zakjan

This comment has been minimized.

zakjan commented Feb 20, 2014

Thanks! Here is complete working solution, for now.

<div ng-if="!hideContent">
  <div ui-view></div>
</div>
$scope.reload = ->
  $state.transitionTo($state.current, $stateParams, reload: true).then ->
    $scope.hideContent = true
    $timeout ->
      $scope.hideContent = false
    , 1
@koganei

This comment has been minimized.

koganei commented Feb 20, 2014

👍 zakjan

1 similar comment
@j-walker23

This comment has been minimized.

j-walker23 commented Feb 21, 2014

👍 zakjan

@vladdancer

This comment has been minimized.

vladdancer commented Feb 25, 2014

Thanks a lot, @zakjan and @rohitranjan1991 ! It works for me too.

@malixsys

This comment has been minimized.

malixsys commented Mar 6, 2014

This works for me now:

            var current = $state.current;
            var params = angular.copy($stateParams);
            $state.transitionTo(current, params, { reload: true, inherit: true, notify: true });
@TimNuman

This comment has been minimized.

TimNuman commented Mar 13, 2014

for those who don't use coffeescript, zakjans solution in normal js:

$scope.reload = function() {
  return $state.transitionTo($state.current, $stateParams, {
    reload: true
  }).then(function() {
    $scope.hideContent = true;
    return $timeout(function() {
      return $scope.hideContent = false;
    }, 1);
  });
};
@giancarloa

This comment has been minimized.

giancarloa commented Mar 14, 2014

hello all... i wanted to see if there are any plans to fix this issue... i basically need the controller to run upon refresh so that i can update the scope... thank you

@nateabele

This comment has been minimized.

Member

nateabele commented Mar 15, 2014

[I] wanted to see if there are any plans to fix this issue.

@giancarloa Yes.

@novarac23

This comment has been minimized.

novarac23 commented Jun 14, 2015

Setting a cache worked fine for refreshing scope for me. Wondering how that will effect the preformance since data is not cached on a route now.

Was there an official fix for this ?

@christopherthielen

This comment has been minimized.

Contributor

christopherthielen commented Jun 16, 2015

@novarac23 officially this has been fixed for some time... Most of the recent comments are related to ionic framework, not ui router.

@LeonanCarvalho

This comment has been minimized.

LeonanCarvalho commented Jun 23, 2015

👍

@hpawe01 's solution doesn't work for me 😢

Should we use location.replace(location.pathname); ?

@georgschlenkhoff

This comment has been minimized.

georgschlenkhoff commented Jul 20, 2015

Why not use trivial this fix:

<a href="javascript:history.go(0)">Reload this page</a>
@brianmyler

This comment has been minimized.

brianmyler commented Jul 21, 2015

First off, apologies, I know this is closed, but I cannot get my controller to re-initialise. I have tried everything that has been mentioned in this ticket and am at my wits end trying to get it working

I have a state that uses a resolve to resolve some data from a resource. I then pass it through to the controller. On initial entry of the state, my resolve is executed and my controller gets the resolved param injected into it, which is as expected. The state displays a view that is a list of orders in a cart.Each row in the list can be deleted and upon deletion, I would like to reload the page to show the updated list.

When i do this, my resolve gets executed, the service that houses the resource gets executed, but it seems that the result is not injected into the controller as expected

@bautistaaa, did you ever manage to get a solution to your problem? I have the exact same problem, and your code is pretty much identical to mine.

I am using the following versions
AngularJS v1.2.28
Angular UI Router v0.2.13

var app = angular.module("orders-app", ['ngResource', 'ui.router', 'datatables', 'ui.bootstrap', 'ngAnimate', 'ngCookies', 'pascalprecht.translate']);

app.config(function($stateProvider, $urlRouterProvider) {
    $stateProvider
        .state('orders', {
            url: '/orders',
            templateUrl: 'angular_modules/orders/views/orders.html'
        })
        .state('orders.detail', {
            url: '/detail',
            templateUrl: 'angular_modules/orders/views/order-details.html',
            resolve: {
                userMetaData: function(userMetadataService){
                    return userMetadataService.getUserMetaData().$promise;
                }
            },
            controller: 'orderDetailsController'
        });
    $urlRouterProvider.otherwise('/orders/detail');

});

app.controller('orderDetailsController', function($rootScope, $scope, $state, $stateParams, $resource, DTOptionsBuilder, DTColumnDefBuilder, ordersService, userMetaData) {

    $scope.model = $scope.model || {};

    $scope.model.userMetaData = userMetaData;

    $scope.model.orderdetails = $scope.model.orderdetails || [];

    $scope.getOrderDetails = function(){
        return ordersService.getCurrentOrderDetails().query({ type: 'current', org: $scope.model.userMetaData.orgId, user: $scope.model.userMetaData.id});
    };

    $scope.getOrderDetails().$promise.then(
        function(data){ 
            $scope.model.orderdetails=data;
        }, 
        function(error){ 
            $scope.errormsg = "error"; 
            alert('error');
        }   
    );

    var errorCallback = function (e) {
        alert('Something went wrong '+e.data.Message);
    };

    var deleteSuccessCallback = function (e, cb) {
        $state.go($state.current, {}, {reload: true, inherit: true, notify: true});
    };

    $scope.deleteOrder = function (row) {
        ordersService.getOrderResource().remove({ id: row.id}, deleteSuccessCallback, errorCallback);
    };

});
@malixsys

This comment has been minimized.

malixsys commented Jul 21, 2015

@brianmyler Plunker or it never happened :)

@brianmyler

This comment has been minimized.

brianmyler commented Jul 22, 2015

@malixsys, you are correct, I should have provided a plunker, in fact, if i had of in the first place, I would have found that my issue was in fact nothing to do with the re-initialisation of my controller.

Turns out the problem was in fact my own stupidity :-). Ther service factory that housed the resource object that gets the user data from a rest endpoint was(well i thought it was) caching the response on the first call to this service. Turns out I had a typo and was in fact caching an empty object, which is why i had the problems 2nd time around.

Anyway, apologies for wasting your time, plunkers first next time :-0

@malixsys

This comment has been minimized.

malixsys commented Jul 22, 2015

@brianmyler No worries! I meant it in jest, but plunkers DO make it easier to diagnose and help.
I am just amazed at this closed issue's longevity, though!

@kszpirak

This comment has been minimized.

kszpirak commented Aug 1, 2015

Super stupid problem. CACHE parameter solves the problem for me...

.state('test.index', {
url: '',
templateUrl: dir + '/test/index.html',
controller: ctrl + 'List',
cache: false,
resolve: {
service: "ListService",
resloveData: function(service, $stateParams) {
return service.get({
listType: 'test'
})
}
}
})

@mgamsjager

This comment has been minimized.

mgamsjager commented Aug 5, 2015

For the people using Ionic. You can disable the cache per view by adding cache-view="false" to the

cache:false in the state definition or $state.go with reload parameter didn't help when using the Ionic framework.

@hirethisdeveloper

This comment has been minimized.

hirethisdeveloper commented Aug 22, 2015

Thanks mgamsjager, doing this in Ionic worked for me:

< ion-view view-title="Locations" cache-view="false" >

@NaomiN

This comment has been minimized.

NaomiN commented Sep 22, 2015

So, what is the current status of this problem and what is the exact fix I need to implement? This is my current code:
if ($scope.searchParameters.categoryId != 0) {
window.console && console.log('Going to category state...')
$state.go('category', { categoryId: $scope.searchParameters.categoryId, createDaily: createDaily },{ reload: true });
}

How should I change it to cause the Init of the controller that is associated with that state to fire?

Thanks in advance.

@NaomiN

This comment has been minimized.

NaomiN commented Sep 22, 2015

This is a very long thread and I am not sure what is exactly solution for my problem. On my index page I have two buttons Create Daily and New. Both of them correspond to the same state and should transition to the same view, but I need a server call to get updated model. I found that init of my second controller associated with that view is not firing after I added a new, clicked Add button to save and then clicked on the Create Daily on the index page. I've added cache: false without any effect. I'm using Google Chrome and AngularJS v1.3.13 for Angular.js and State-based routing for AngularJS

  • @Version v0.2.8 for ui-router.js. What should be my solution to make sure my API call is happening when I press New/Save then CreateDaily buttons (or other way around)?
@NaomiN

This comment has been minimized.

NaomiN commented Sep 24, 2015

What is the official version of ui-router.js? Nuget only offers 0.2.08

Where and how can I grab the latest?

@malixsys

This comment has been minimized.

@NaomiN

This comment has been minimized.

NaomiN commented Sep 24, 2015

Thanks a lot, what about non-min version as well?

@IainCole

This comment has been minimized.

@NaomiN

This comment has been minimized.

NaomiN commented Sep 24, 2015

Latest ui-router.js file didn't resolve the issue for me. My code is the following:

$state.go('category', { categoryId: $scope.searchParameters.categoryId, createDaily: createDaily },
{ reload: true, inherit: true, notify: true });

The Init of the corresponding controller is not firing and the server's method is not called.

@NaomiN

This comment has been minimized.

NaomiN commented Sep 24, 2015

Looks like the issue I was having was actually related to a bug we had in our directive. Once we commented out 1 line of code (important, though), I didn't have the issue anymore

@malixsys

This comment has been minimized.

malixsys commented Sep 25, 2015

This thread is undead.

@martijn-vdm

This comment has been minimized.

martijn-vdm commented Sep 28, 2015

@mgamsjager thank you so much for your hint! After hours of debugging and searching for less-than-optimal alternatives, adding cache-view="false" tom my ionic view for reloading the same view worked!

@angelxmoreno

This comment has been minimized.

angelxmoreno commented Oct 4, 2015

@mgamsjager I owe you a beer!

@edgahan

This comment has been minimized.

edgahan commented Oct 26, 2015

Just quickly, in case it helps other: Adding cache: false to the state did not work for me, I had to add cache-view on the ion-view element like this: <ion-view title="my title" cache-view="false">

@iffakhry

This comment has been minimized.

iffakhry commented Nov 30, 2015

@hpawe01 thanks, work for me

@seyfiaslan

This comment has been minimized.

@neolectron

This comment has been minimized.

neolectron commented Aug 16, 2016

i lost 4hours on this bug, gg

@justinmichaels

This comment has been minimized.

justinmichaels commented Oct 19, 2016

Why was this closed? I'm using v0.3.1 and this issue still is happening. I've even tried multiple of these solutions without any luck.

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

I'm still not seeing my controller constructor being hit.

@eddiemonge

This comment has been minimized.

Member

eddiemonge commented Oct 19, 2016

It was closed because it was fixed in 7344342

If you are still experiencing it, please open a new issue to track it.

@hhsadiq

This comment has been minimized.

hhsadiq commented Nov 28, 2016

I was having this issue, able to solve it using solution mentioned in ui-sref-active section of docs.

<a ui-sref="home" ui-sref-opts="{reload: true}">Home</a>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment