14

I have several services which uses a webservice and caches a lot of the results.By caching i mean storing in a variable on the service. When a user logs out the data should be cleared. The services looks like the following (simplified version):

class DataService   {

  private data;

  constructor($http)
  {
     $http.get(url).then((response) => 
       { 
          this.data = response.data;
       });
  }

}

Which is typescript, but resolves to something like this:

var DataService = (function () {
    function DataService($http) {
        var _this = this;
        $http.get(url).then(function (response) {
            _this.data = response.data;
        });
    }
    return DataService;
})();

I could clear the data using the answer in This Question Which is doing something like this:

$rootScope.on('logout',function(){
  this.data = [];
});

However, this is a lot of code when we have multiple services and controllers. And we all know that this new guy will add some new data to a service and he forgets to add it to the logout sequence. It is simply a bad practice.

Similarily, data are stored on $scope in various parts of the application and this must be cleared as well. The scope is rather simple as constructors for the controllers are loaded on each page visits and will then override the data.

One propossed solution is to make a refresh, however this gives horrible user experiences.

One solution could be to make angular believe that the services have never been created or reload angular completely.

What is the best way to do this? Is it bad to store data in variables on services?

Cœur
  • 37,241
  • 25
  • 195
  • 267
CodeTower
  • 6,293
  • 5
  • 30
  • 54
  • 1
    Interesting question. Surely not *all* of your services rely on the logged in user? TypeScript could come in useful here. You could define an interface, say `ILoggedInUserService` which exposes a `tearDown()` method. That would force the developer to implement this method for all applicable services. You could then [enumerate](http://stackoverflow.com/questions/19411502/angular-get-list-of-all-registered-services) and execute on log out – CodingIntrigue Oct 23 '14 at 07:21
  • 5
    I deal with it by broadcasting an event, and all relevant services clean up their data by listening on that event. This keep the code neat with no inter-dependencies. – harishr Oct 23 '14 at 07:30

2 Answers2

10

You can create a service which is responsible clearing all the the data from the other services. In this case you only have to call the "clear" method of this service, and implement the individual clear calls inside of this one (so only implemented once).

This gives you also the advantage that you have an overview of which services data need to be cleared all the time, since you might have exceptions in the future.

Also see this answer for your reference: Injecting a service into another service in angularJS

Community
  • 1
  • 1
Torsten Engelbrecht
  • 13,318
  • 4
  • 46
  • 48
  • You still need to specify the individual data, unless we store all services data in a separate object for each service. Then deleting this object would clear it. – CodeTower Oct 23 '14 at 09:10
  • @Kabahango, did you figure out a way get around this without having to specify every property you want to reset? I feel like window reload option is probably a better option than this. – m0g Jul 13 '16 at 21:10
  • Not exactly. But a good approach is to make "Repository pattern" such that all data in your app is stored in one or more repositories. This is not a workaround per se, but it is a good design pattern. – CodeTower Jul 15 '16 at 08:49
  • Further more using resolves can make it easier to maintain which data a controller will get – CodeTower Jul 15 '16 at 08:49
5

you can use a full page refresh:

$window.location.reload();

this will restart the whole state of your application

another solution could be to store everything in session storage and then clear it on log out:

sessionStorage.clear();
Marian Ban
  • 8,158
  • 1
  • 32
  • 45
  • 9
    Using the `$window.location.reload()` gives bad user experience IMO. I have atleast not found a clever foolproof way to do it where the user does not see the page load and then it reloads. – CodeTower Oct 23 '14 at 09:06