Persist data from the previous state while going back – Angular 1.4 UI Router

Issue

I have a web application wherein there are many states based on the URL change.
There is an User Management page (containing a search Input control) which lists the Users based on search results.

When clicking a particular User, the User details would get loaded through a different state. I put a Button to go back to the User Management page.

The requirement is to persist the search result in the User Management page when coming back from User Detail page.

Kindly help me achieve this requirement, without making new XHR to fetch the search lists again.

.state('userManagement', {
    url: '/user-management',
    templateUrl: 'components/userManagement/UserMgmt.view.html',
    controller: 'UserMgmtCtrl',
    controllerAs: 'vm'
  })
  .state('userDetail', {
    url: '/user-detail/:userId',
    templateUrl: 'components/userManagement/UserDetail.view.html',
    controller: 'UserDetailCtrl',
    controllerAs: 'vm'
  })

Should I have nested states or something to achieve this?

Solution

You can add resolves in your states to inject the stuff you want in your controllers.

Use an angular service to store your stuff because they are singletons, meaning they only get instantiated once, therefore the data stored in them is always the same.

.state('userManagement', {
    url: '/user-management',
    templateUrl: 'components/userManagement/UserMgmt.view.html',
    controller: 'UserMgmtCtrl',
    controllerAs: 'vm',
    resolve: {
        yourStuff: function (StorageService) {
            return StorageService.getStuff();
        } 
    }
})
.state('userDetail', {
    url: '/user-detail/:userId',
    templateUrl: 'components/userManagement/UserDetail.view.html',
    controller: 'UserDetailCtrl',
    controllerAs: 'vm',
    resolve: {
        yourStuff: function (StorageService) {
            return StorageService.getStuff();
        } 
    }
})

app.factory("StorageService", function () {
    var yourStuffStorage = {
        "initial": "stuff"
    };

    return {
          getStuff: getStuff,
          setStuff: setStuff
    };

    function getStuff () {
        return yourStuffStorage;
    }

    function setStuff (newStuff) {
        yourStuffStorage = angular.copy(newStuff); 
    }
})

app.controller("UserMgmtCtrl", function (yourStuff) {
    console.log("do stuff with your stuff 1", yourStuff);
});

app.controller("UserDetailCtrl", function (yourStuff) {
    console.log("do stuff with your stuff 2", yourStuff);
});

If you were wondering why didn’t we inject the service and query for the data, that’s because it’s considered best practice in ui-router to fetch data (sometimes via promises) and pass the result to the controller, so that the state won’t load before the data loads.

Hope this helps 🙂

Answered By – Protozoid

Answer Checked By – Timothy Miller (AngularFixing Admin)

Leave a Reply

Your email address will not be published.