23

What would be the best way to save data between routes?
So I have a form that has 4 steps and I would like for the data from a previous step to be carried over to the next step.

Right now, I'm using a "service" to save the data, which works. However, the problem is since a "service" is singleton, navigating away from the form, and coming back to it, will still has all the data from a previous incomplete or abandoned form.

Is there a good way to solve this kind of situation?

Thank you,
Tee

teepusink
  • 27,444
  • 37
  • 107
  • 147
  • 1
    possible duplicate of [Angularjs, passing scope between routes](http://stackoverflow.com/questions/13882077/angularjs-passing-scope-between-routes) – Dan Dascalescu Oct 24 '14 at 11:58

2 Answers2

29

Why don't you enhance the service to take care of deleting the stored data when:

  • The user does not complete the form and navigates away from the entire form submission process
  • The user submits the form

Basically, you could enhance your service as follows:

myApp.factory('myService', function () {
    var formData = {};

    return {
        getData: function () {
            //You could also return specific attribute of the form data instead
            //of the entire data
            return formData;
        },
        setData: function (newFormData) {
            //You could also set specific attribute of the form data instead
            formData = newFormData
        },
        resetData: function () {
            //To be called when the data stored needs to be discarded
            formData = {};
        }
    };
});

Your controller could then be as follows:

myApp.controller('FirstStepCtrl', ['$scope', 'myService', function ($scope, myService) {
    //This is the controller of the first step in the form
    //Reset the data to discard the data of the previous form submission
    myService.resetData();

    //Remaining Logic here
}]);

myApp.controller('LastStepCtrl', ['$scope', 'myService', function ($scope, myService) {
    //This is the controller of the last step in the form

    //Submits the form
    $scope.submitForm = function () {
        //Code to submit the form

        //Reset the data before changing the route - assuming successful submission
        myService.resetData();

        //Change the route
    };

    //Remaining Logic here
}]);

Another alternative is to call the service's resetData() function when the route changes to something that is not within the form application. If you have something like a Parent Controller for the Form step controllers, then in that controller, you could keep a watch over the route change:

$scope.$on('$routeChangeStart', function() { 
   //Use $location.path() to get the current route and check if the route is within the 
   //form application. If it is, then ignore, else call myService.resetData()

   //This way, the data in the forms is still retained as long as the user is still
   //filling up the form. The moment the user moves away from the form submission process,
   //for example, when explicitly navigating away or when submitting the form, 
   //the data is lost and no longer available the next time the form is accessed
 });
callmekatootie
  • 10,989
  • 15
  • 69
  • 104
  • Thanks @callmekatootie. Yes, having a resetData function is what I have in mind currently. I just feel like it is somewhat hacky that I need to keep track of paths. I'm thinking angular would be able to do a double template insertion, i.e if you have a controller in the html tag, it persists regardless of route. So in this case, I have a parent controller that won't get reloaded when route change, but they also have sub controller for each of the steps. I just don't know if this is possible to do. – teepusink May 29 '13 at 16:58
2

Services will persist throughout your applications's life. So you should not have any problems. All you need to do is to create a Service and inject it to the controllers that need to access it. For instance, below I have injected User service to controllers.

Just use different controllers for each of your routes so that your model inside scope won't be overridden.

First controller for first route,

app.controller("FirstPageController", function($scope,User){   
    $scope.user = User;
    $scope.user.firstName  = "Emre";
    $scope.user.secondName = "Nevayeshirazi";
});

Second controller for second route,

app.controller("SecondPageController", function($scope,User){ 
    $scope.user = User;  
    $scope.user.age = 24;
});
emre nevayeshirazi
  • 18,983
  • 12
  • 64
  • 81
  • 4
    This would be a poor solution. Forms usually don't already contain data when the user attempts to fill them up. According to the question, when a user fills a form up, submits the form and then comes back to fill the same form again, the user should not be presented with the old form data. Your solution proposes to have default values for the form fields which is not what the user expects here. – callmekatootie May 29 '13 at 05:38
  • Also, why call the service when you plan to override the data anyway in the controller directly instead of mapping the data from the view? – callmekatootie May 29 '13 at 06:01