Skip to main content
deleted 12 characters in body; edited tags; edited title
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Member-Specific Object Cachespecific object cache for Angular

  1. Cache objects by type;type
  2. Prevent collisions and conflicts;conflicts
  3. Find objects by like property; and,property
  4. Ensure caches are separated by the logged in user.

I am using Satellizer to determine if the user is logged in. Each object's service will act as a wrapper to this service and pass in it'sits typeName property (probably set as a constant in the calling service).

Member-Specific Object Cache for Angular

  1. Cache objects by type;
  2. Prevent collisions and conflicts;
  3. Find objects by like property; and,
  4. Ensure caches are separated by the logged in user.

I am using Satellizer to determine if the user is logged in. Each object's service will act as a wrapper to this service and pass in it's typeName property (probably set as a constant in the calling service).

Member-specific object cache for Angular

  1. Cache objects by type
  2. Prevent collisions and conflicts
  3. Find objects by like property
  4. Ensure caches are separated by the logged in user

I am using Satellizer to determine if the user is logged in. Each object's service will act as a wrapper to this service and pass in its typeName property (probably set as a constant in the calling service).

Source Link
G. Deward
  • 204
  • 1
  • 5

Member-Specific Object Cache for Angular

I'm trying to build a reusable object cache for Angular. The goal is to:

  1. Cache objects by type;
  2. Prevent collisions and conflicts;
  3. Find objects by like property; and,
  4. Ensure caches are separated by the logged in user.

I am using Satellizer to determine if the user is logged in. Each object's service will act as a wrapper to this service and pass in it's typeName property (probably set as a constant in the calling service).

(function () {

    'use strict';

    angular
        .module('blocks.object-cache');

    objectCache.$inject = ['CacheFactory', '$auth'];

    function objectCache(CacheFactory, $auth) {

        var _options = {
            maxAge : (60 * 60 * 1000),
            deleteOnExpire : 'passive',
            storageMode : 'localStorage'
        };

        var service = {
            setOptions          : setOptions,
            getCache            : getCache,

            clear               : clear,

            getAll              : getAll,
            getItem             : getItem,
            getItems            : getItems,

            putItem             : putItem,
            putItems            : putItems,

            getItemsByKey       : getItemsByKey,
            getItemByKeyFirst   : getItemByKeyFirst,
            getItemByKeySingle  : getItemByKeySingle,


            removeItemsByKey    : removeItemsByKey,
            removeItemByKey     : removeItemByKey,

            putItemsByKey       : putItemsByKey,
            putItemByKey        : putItemByKey
        };

        return service;
        ////////////////////////////////////////////////////////////////////////////////

        function setOptions (options) {
            options = options || {};
            options.maxAge = options.maxAge = _options.maxAge;
            options.deleteOnExpire = options.deleteOnExpire = _options.deleteOnExpire;
            options.storageMode = options.storageMode = _options.storageMode;
            _options = options;
        }
        function getCache(typeName) {
            var cacheName = [getUserId(), normalizeTypeName(typeName || 'objects')].join('_');
            var cache = CacheFactory(cacheName);
            if (cache) { return cache; }
            cache = CacheFactory(cacheName, _options);
            return cache;
        }

        function clear (typeName) {
            var cache = getCache(typeName);
            cache.removeAll();
            return (!cache.keys() || (cache.keys().length < 1));
        }

        function getAll (typeName) {
            var cache = getCache(typeName);
            var result = [];
            (cache.keys() || []).forEach(function(key){
                result.push(cache(key));
            });
            return result;
        }
        function getItem(typeName, id) {
            if (typeof id == 'undefined' || !id.trim) { return null; }
            var cache = getCache(typeName);
            return cache.get(id);
        }
        function getItems(typeName, ids) {
            var cache = getCache(typeName),
                result = [],
                _ids   = [];
            (ids || []).forEach(function(id){
                if (_ids.indexOf(id) < 0) {
                    _ids.push(id);
                    var item = cache.get(id);
                    if (item) { result.push(item); }
                }
            });
            return result;
        }

        function putItem(typeName, item, id, refresh) {
            if (typeof item == 'undefined') { return false; }
            if (typeof id == 'undefined' || !id.trim) { return false; }
            var cache = getCache(typeName);
            var existing = cache.get(id);
            if (existing && !refresh) { return true; }
            if (existing) { cache.remove(id); }
            cache.put(item, id);
            return (!!cache.get(id));
        }
        function putItems(typeName, items, idField, refresh) {
            var cache = getCache(typeName);
            (items || []).forEach(function(item){
                var id = item[idField];
                if (typeof id != 'undefined') {
                    var existing = cache.get(id);
                    if (existing && !!refresh) { cache.remove(id); }
                    if (!existing || !!refresh) { cache.put(item, id); }
                    if (!cache.get(id)) { return false; }
                }
            });
            return true;
        }

        function getItemsByKey(typeName, key, value, isCaseSensitive) {
            var result = [];
            (getAll(typeName) || []).forEach(function(item){
                var itemValue = item[key];
                if (typeof itemValue != 'undefined') {
                    if ((typeof value == 'string') && (typeof itemValue == 'string') && (!isCaseSensitive || value.toLowerCase() == itemValue.toLowerCase())) {
                        result.push(item);
                    } else if (((typeof value) == (typeof itemValue)) && (value == itemValue)) {
                        result.push(item);
                    } else {
                        // Other scenarios?
                    }
                }
            });
            return result;
        }
        function getItemByKeyFirst(typeName, key, value, isCaseSensitive) {
            var items = getItemsByKey(typeName, key, value, isCaseSensitive) || [];
            return (items.length > 0) ? items[0] : null;
        }
        function getItemByKeySingle(typeName, key, value, isCaseSensitive) {
            var items = getItemsByKey(typeName, key, value, isCaseSensitive) || [];
            return (items.length === 0) ? items[0] : null;
        }
    
        function removeItemsByKey (typeName, keyField, values, isCaseSensitive) {
            var cache = getCache(typeName),
                keysToRemove = [];
            (cache.keys() || []).forEach(function(key){
                var item        = cache.get[key],
                    itemValue   = item[keyField];
                if (typeof itemValue != 'undefined') {
                    for (var v = 0; v < (values || []).length; v += 1) {
                        if ((typeof values[v] == 'string') && (typeof itemValue == 'string') && (!isCaseSensitive || values[v].toLowerCase() == itemValue.toLowerCase())) {
                            keysToRemove.push(key);
                            break;
                        } else if (((typeof values[v]) == (typeof itemValue)) && (values[v] == itemValue)) {
                            keysToRemove.push(key);
                            break;
                        } else {
                            // Other scenarios?
                        }
                    }
                }
            });
            var success = true;
            keysToRemove.forEach(function(key){
                cache.remove(key);
                if (cache.get(key)) { success = false; }
            });
            return success;
        }
        function removeItemByKey (typeName, keyField, value, isCaseSensitive) {
            return removeItemsByKey(typeName, keyField, [value], isCaseSensitive);
        }

        function putItemsByKey(typeName, items, keyField, refresh, isCaseSensitive) {
            if (!!refresh) {
                var values  = _.map((items || []), keyField);
                if (!removeItemsByKey(typeName, keyField, values, isCaseSensitive)) { return false; }
            }
            var cache = getCache(typeName);
            (items || []).forEach(function(item){
                var id = item[keyField];
                if (typeof value != 'undefined') { cache.put(item, id); }
                if (!cache.get(id)) { return false; }
            });
            return true;
        }
        function putItemByKey(typeName, item, keyField, refresh, isCaseSensitive) {
            return putItemsByKey(typeName, [item], keyField, refresh, isCaseSensitive);
        }

        function getUserId () {
            return $auth.isAuthenticated() ? ($auth.getPayload().sub || 'unknown') : 'public';
        }
        function normalizeTypeName (typeName) {
            return typeName.split('.').join('-');
        }
    }

})();