0

Hi I have a pretty large (and growing) AngularJS form that consists of several pages of inputs. On the back end there is only a single post endpoint that saves to the db. I am currently using $cookies to locally save the data from prior steps in case the user wants to go back and edit something. Is it dangerous or a bad idea to do it this way? It seems to work really well so far but I am concerned I am doing something stupid that I don't know about.

I am using components and angular-ui-router to route views like this:

namespace NewClientForm {
angular
    .module('app', ['ui.bootstrap', 'ngCookies', 'ui.router', 'google.places', 'cwill747.phonenumber'])
    .config(function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/clientInfo');
        $stateProvider
            .state('clientInfo', {
                url: '/clientInfo',
                template: '<h3>Client Info</h1></br><clientinfo></clientinfo>'
            })
            .state('billing', {
                url: '/billing',
                template: '<h3>Billing</h1></br><billing></billing>'
            })
            .state('licensing', {
                url: '/licensing',
                template: '<h3>Licensing</h1></br><licensing></licensing>'
            })
            .state('users', {
                url: '/users',
                template: '<h3>Add Users</h1></br><users></users>'
            })
            .state('quoting', {
                url: '/quoting',
                template: '<h3>Quoting Preferences</h1></br><quoting></quoting>'
            });
    })
    .component('billing', {
        templateUrl: 'app/form/templates/billing.html',
        bindings: {},
        controller: 'FormController'
    })
    .component('clientinfo', {
        templateUrl: 'app/form/templates/clientInfo.html',
        bindings: {},
        controller: 'FormController'
    })
    .component('licensing', {
        templateUrl: 'app/form/templates/licensing.html',
        bindings: {},
        controller: 'FormController'
    })
    .component('users', {
        templateUrl: 'app/form/templates/users.html',
        bindings: {},
        controller: 'FormController'
    })
    .component('spinner', {
        templateUrl: 'app/form/templates/spinner.html',
        bindings: {},
        controller: 'FormController'
    })
    .component('quoting', {
    templateUrl: 'app/form/templates/quoting.html',
    bindings: {},
    controller: 'FormController'
});};

Then I am using the putObject method on $cookies to save the data like this:

Controller:

save = (name: string, obj: any, configObj: any, state: string) => {
        this.$cookies.putObject(name, obj, configObj);
        this.$log.debug(this.$cookies.getAll());
        this.$state.go(state);
    };

View:

<button class="btn btn-primary" ng-if="!clientInfoForm.$invalid"
        style="float:right;" 
        ng-click="$ctrl.save('clientInfo', $ctrl.clientInfo, {expires:$ctrl.expireDate}, 'billing')">
        Next
</button>

Lastly, I am using $cookies.getObject in my function to populate my ng-model(s) from the $cookie:

populateFromCookie = () => {
        this.clientInfoCookie = this.$cookies.getObject('clientInfo');            
        if (this.clientInfoCookie) {
            if (this.clientInfoCookie.hasOwnProperty('FirstName')) {
                this.clientInfo.FirstName = this.clientInfoCookie.FirstName;
            };
            if (this.clientInfoCookie.hasOwnProperty('LastName')) {
                this.clientInfo.LastName = this.clientInfoCookie.LastName;
            };
            if (this.clientInfoCookie.hasOwnProperty('title')) {
                this.clientInfo.title = this.clientInfoCookie.title;
            };
        };
    };  

Any constructive criticism or suggestions on how I could improve this would be much appreciated. Thanks!

kennypowers
  • 199
  • 1
  • 8

2 Answers2

2

It all depends on how sensitive your information is. Your approach is definitely valid but has one fundamental problem which is probably the reason for why cookies were created in the first place.Generally, sensitive information is not meant to be stored in cookies.

Such information is best stored on the server side.If you are not storing the data in your database, potentially you could lose all your data you have stored in the cookie, when a user clear his browser cookie information.

You can consider using WEB SQL or localStorage if you want to store information locally in your browser, but storing in the back-end is always preferable.

Please consider reading the stats below, if you think using cookies is a good idea.

Typically, the following are allowed in browser for cookies

300 cookies in total,

4096 bytes per cookie,

20 cookies per domain,

81920 bytes per domain

Pramod_Para
  • 671
  • 3
  • 10
1

I have dealt with exactly the same situation and with a lot of data I found using sessionStorage was the best solution for me.

Have a look at this post on What is the max size of localStorage values?

Simply serialize to store and de-serialize on retrieval and your good to go.

Is it dangerous or a bad idea to do it this way?

If you are dealing with sensitive information, of course you want to get it to the server as soon as you can and then remove it from your chosen method of storage.

If a user is entering data, they would expect their data to be there for the duration of their session in most cases anyway. sessionStorage is good as it will only be accessible while and by the window that created it is open.

Community
  • 1
  • 1
cnorthfield
  • 3,384
  • 15
  • 22
  • I ended up using https://github.com/gsklee/ngStorage and it's working great so far with less code in my controller. Thanks. – kennypowers Mar 24 '17 at 17:12