AngularJS: ui-router Redirect view on success & refresh scope with new contents

Gravy picture Gravy · May 21, 2014 · Viewed 15.4k times · Source

I am migrating from ng-view to ui-view.

In my controller, upon successful create / update / delete, I would like to redirect to an index view with the newly updated / created / deleted data.

I currently do this using $state.go.

app.controller('AdminSupplierCreateController', ['$scope', '$state', 'Supplier', 
    function ($scope, $state, Supplier) {
        $scope.h1 = "Register a new Supplier";

        $scope.store = function()
        {
            Supplier.post($scope.supplier)
                .then(
                    function() {
                        console.log("Successfully Created Supplier");
                        $state.go('admin.supplier');
                    },
                    function(response) {
                        console.log("Error with status code: " + response.status);
                    }
                );
        };
}]);

The problem is that when the $state is changed, the scope is not updated. It appears as though the original admin.supplier scope data is not being refreshed.

I have tried refreshing the ui-view with $state.reload() before setting the scope in AdminSupplierIndexController.

app.controller('AdminSupplierIndexController', ['$scope', '$state', 'suppliers', 
    function ($scope, $state, suppliers) {
        $state.reload();
        $scope.suppliers = suppliers;
}]);

Doing this makes the get request to api/v1/suppliers, however it doesn't actually show the updated scope unless I either hit the refresh button on the browser or manually navigate to a different state, then navigate back again.

$stateProvider
    ...
    .state('admin.supplier', {
        url : "/supplier",
        templateUrl : 'templates/admin/supplier/index.html',
        controller: "AdminSupplierIndexController",
        resolve: {
            suppliers: ['Supplier', function(Supplier) {
                return Supplier.getList();
            }]
        }
    })
    .state('admin.supplier.create', {
        url : "/create",
        templateUrl : 'templates/admin/supplier/create.html',
        controller: "AdminSupplierCreateController"
    })

Solution:

app.controller('AdminSupplierCreateController', ['$scope', '$state', 'Supplier', 
    function ($scope, $state, Supplier) {
        $scope.h1 = "Register a new Supplier";

        $scope.store = function() {
            Supplier.post($scope.supplier)
                .then(
                    function() {
                        console.log("Successfully Created Supplier");

                                            // Force Reload on changing state
                                            $state.go('admin.supplier', {}, {reload: true});
                    },
                    function(response) {
                        console.log("Error with status code: ", response.status);
                    }
                );
        };
}]);

Answer

user2847643 picture user2847643 · May 21, 2014

This happens because you move to parent state which is already created. You would have to signal to ui-router that you do want to reload it.

I think you might be looking for the reload option of $state.go(). Refer to the docs.

Also, a sort of a workaround might be to move the "index" state to a sibling state of edit. admin.supplier.index or so. Then it would be destroyed as you transition to admin.supplier.edit and recreated when you transition back and no additional options are necessary.

Also as a side note I guess it would be considered good practice to use $state.go instead of $location whenever possible.