Skip to content
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
Closed

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

ghengeveld opened this issue Nov 14, 2013 · 170 comments
Assignees
Labels
Milestone

Comments

@ghengeveld
Copy link

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
Copy link

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
Copy link
Author

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
Copy link

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
Copy link

👍

@panga
Copy link

panga commented Dec 2, 2013

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

@nateabele
Copy link
Contributor

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

@lc-nyovchev
Copy link

👍

@johnculviner
Copy link

👍 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
Copy link

Have you tried flipping the reload flag on transitionTo?

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

@johnculviner
Copy link

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
Copy link

zakjan commented Jan 28, 2014

What is state of this bug?

@nateabele
Copy link
Contributor

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

@johnculviner
Copy link

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

@zakjan
Copy link

zakjan commented Jan 31, 2014

👍 looking forward to it

@sausaw
Copy link

sausaw commented Feb 4, 2014

👍

@marccantwell
Copy link

@nateabele any updates?

@PeterMajer
Copy link

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
Copy link

@PeterMajer great hack, i was using

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

@zakjan
Copy link

zakjan commented Feb 13, 2014

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

@rohitranjan1991
Copy link

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
Copy link

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
Copy link

koganei commented Feb 20, 2014

👍 zakjan

1 similar comment
@j-walker23
Copy link

👍 zakjan

@vladdancer
Copy link

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

@malixsys
Copy link

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
Copy link

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
Copy link

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
Copy link
Contributor

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

@giancarloa Yes.

@novarac23
Copy link

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
Copy link
Contributor

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

@LeonanCarvalho
Copy link

👍

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

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

@ghost
Copy link

ghost commented Jul 20, 2015

Why not use trivial this fix:

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

@brianmyler
Copy link

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
Copy link

@brianmyler Plunker or it never happened :)

@brianmyler
Copy link

@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
Copy link

@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
Copy link

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
Copy link

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
Copy link

Thanks mgamsjager, doing this in Ionic worked for me:

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

@NaomiN
Copy link

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
Copy link

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
Copy link

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
Copy link

@NaomiN
Copy link

NaomiN commented Sep 24, 2015

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

@IainCole
Copy link

@NaomiN
Copy link

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
Copy link

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
Copy link

This thread is undead.

@martijn-vdm
Copy link

@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
Copy link

@mgamsjager I owe you a beer!

@edgahan
Copy link

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
Copy link

@hpawe01 thanks, work for me

@seyfiaslan
Copy link

@neolectron
Copy link

i lost 4hours on this bug, gg

@justinmichaels
Copy link

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
Copy link
Contributor

It was closed because it was fixed in 7344342

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

@hhsadiq
Copy link

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
Labels
Projects
None yet
Development

No branches or pull requests