Search code examples
angularjsangularjs-injector

AngularJS service injection based on feature detection


In my Angular app, I need to create a persistence service interface that calls a concrete implementation based on the persistence mechanisms available in my browser. I am thinking of implementing this using a generic storageService that calls a specific storageService that understands a storage mechanism.

For example, the generic storageService will provide the following interface:

angular
    .module('app.storage')
    .factory('storageService', storageService);

function storageService() {
    return {
        saveItem: saveItem,
        getItem: getItem
    }

    ...
}

There will be multiple implementations of the storageService, e.g. localStorageService, indexedDbStorageService, webSqlStorageService.

What is the best way to dynamically inject a concrete storage service based on browser features. For example,

if (isWebSqlAvailable()) {
    // inject webSqlStorageService 
}
else if (isIndexedDbAvailable() {
    // inject indexedDbStorageService 
}
else if (isLocalStorageAvailable() {
    // inject localStorageService 
}

Solution

  • angular
      .module('app.storage')
      .factory('storageService', ['$injector', storageService]);
    
      function storageService($injector) {
    
      var svc;
      if (isWebSqlAvailable()) {
        svc = $injector.get('webSqlService');
      }
      else if (isIndexedDbAvailable() {
        svc = $injector.get('indexedDbService');
      }
      else if (isLocalStorageAvailable() {
        svc = $injector.get('localStorageService');
      }
    
      return svc;
    }
    
    
    angular
      .module('app.storage').factory('webSqlService', webSqlService);
    
    function webSqlService(){
       return {
          saveItem: saveItem,
          getItem: getItem
       }
    
       function getItem(){
    
       }
    
       function saveItem(){
    
       }
    
    }
    
    angular
      .module('app.storage').factory('indexedDbService', indexedDbService);
    
    function indexedDbService(){
       return {
          saveItem: saveItem,
          getItem: getItem
       }
    
       function getItem(){
    
       }
    
       function saveItem(){
    
       }
    
    }
    

    And then, you will just have to inject your storageService everywhere you want.