ts/service/LocalStorageService.ts - StructureJS

StructureJS

0.15.2

A class based utility library for building modular and scalable web platform applications. Features opt-in classes and utilities which provide a solid foundation and toolset to build your next project.

File: ts/service/LocalStorageService.ts

  1. import LocalStorageEvent from '../event/LocalStorageEvent';
  2. import EventDispatcher from '../event/EventDispatcher';
  3. import BaseModel from '../model/BaseModel';
  4.  
  5. class LocalStorageFallback {
  6.  
  7. private _data:any = {};
  8.  
  9. constructor() {
  10. console.warn(`window.localStorage is not working. StructureJS LocalStorageService will use an in memory version.`);
  11. }
  12.  
  13. public setItem(key:string, value:string):any {
  14. return this._data[key] = String(value);
  15. }
  16.  
  17. public getItem(key:string):any {
  18. return (this._data.hasOwnProperty(key) === true) ? this._data[key] : null;
  19. }
  20.  
  21. public removeItem(key:string):any {
  22. return delete this._data[key];
  23. }
  24.  
  25. public clear():any {
  26. return this._data = {};
  27. }
  28.  
  29. public key(index:number):any {
  30. return Object.keys(this._data)[index];
  31. }
  32.  
  33. public get length() {
  34. return Object.keys(this._data).length;
  35. }
  36.  
  37. }
  38.  
  39. /**
  40. * The LocalStorageService...
  41. *
  42. * @class LocalStorageService
  43. * @extends EventDispatcher
  44. * @module StructureJS
  45. * @submodule controller
  46. * @requires Extend
  47. * @requires EventDispatcher
  48. * @requires LocalStorageEvent
  49. * @requires BaseModel
  50. * @constructor
  51. * @author Robert S. (www.codeBelt.com)
  52. * @example
  53. * this._localStorageController = new LocalStorageService();
  54. * this._localStorageController.set('someName', { value: 'something'});
  55. */
  56. class LocalStorageService extends EventDispatcher
  57. {
  58. /**
  59. * Current user namespace. The namespace is optional.
  60. *
  61. * @property _namespace
  62. * @type {string}
  63. * @default defaultNamespace
  64. * @optional
  65. * @protected
  66. */
  67. protected _namespace:string = '';
  68.  
  69. /**
  70. * A reference to window.localStorage for faster access.
  71. *
  72. * @property _localStorage
  73. * @type {Storage}
  74. * @protected
  75. */
  76. protected _localStorage:Storage = null;
  77.  
  78. constructor(namespace:string = '')
  79. {
  80. super();
  81.  
  82. this._namespace = namespace;
  83.  
  84. try {
  85. this._localStorage = window.localStorage;
  86. } catch (error) {
  87. window['StructureJS_localStorageServiceFallback'] = window['StructureJS_localStorageServiceFallback'] || new LocalStorageFallback();
  88.  
  89. this._localStorage = window['StructureJS_localStorageServiceFallback'];
  90. }
  91.  
  92. window.addEventListener('storage', this._onLocalStorageEvent.bind(this));
  93. }
  94.  
  95. /**
  96. * Set storage namespace
  97. *
  98. * @method setNamespace
  99. * @param namespace
  100. * @returns {string}
  101. * @example
  102. * this._localStorageController.setNamespace('myNamespace~');
  103. */
  104. public setNamespace(namespace:string):void
  105. {
  106. this._namespace = namespace;
  107. }
  108.  
  109. /**
  110. * Get storage namespace
  111. *
  112. * @method getNamespace
  113. * @returns {string}
  114. * @example
  115. * const currentSetNamespace = this._localStorageController.getNamespace();
  116. */
  117. public getNamespace():string
  118. {
  119. return this._namespace;
  120. }
  121.  
  122. /**
  123. * Add a key/value pair to localStorage.
  124. *
  125. * @method set
  126. * @param key {string}
  127. * @param data {Object}
  128. * @param [useNamespace=false] {boolean}
  129. * @return {boolean}
  130. * @example
  131. * this._localStorageController.set('someName', { value: 'something'});
  132. *
  133. * // If you set a namespace you would pass 'true' into the third parameter.
  134. * this._localStorageController.set('someName', { value: 'something'}, true);
  135. */
  136. public set(key:string, data:any, useNamespace:boolean = false):boolean
  137. {
  138. if (useNamespace)
  139. {
  140. key = this.getNamespace() + key;
  141. }
  142.  
  143. if (data instanceof BaseModel)
  144. {
  145. data = <BaseModel>data.toJSON();
  146. }
  147.  
  148. data = JSON.stringify(data);
  149.  
  150. try
  151. {
  152. this._localStorage.setItem(key, data);
  153. return true;
  154. }
  155. catch (error)
  156. {
  157. return false;
  158. }
  159. }
  160.  
  161. /**
  162. * Retrieves the current value associated with the Local Storage key.
  163. *
  164. * @method get
  165. * @param key {string}
  166. * @param [useNamespace=false] {string}
  167. * @returns {any}
  168. * @example
  169. * this._localStorageController.setNamespace('myNamespace~');
  170. */
  171. public get(key:string, useNamespace:boolean = false):any
  172. {
  173. if (useNamespace)
  174. {
  175. key = this.getNamespace() + key;
  176. }
  177.  
  178. let value = this._localStorage.getItem(key);
  179. if (value)
  180. {
  181. try
  182. {
  183. value = JSON.parse(value);
  184. }
  185. catch (error)
  186. {
  187. // We are assuming the error is because value being parsed is a plain string with spaces.
  188. value = value;
  189. }
  190. }
  191.  
  192. return value;
  193. }
  194.  
  195. /**
  196. * Returns all items in local storage as an Object with key and value properties or
  197. * returns all items with a certain namespace.
  198. *
  199. * @method getAll
  200. * @param [namespace=null] {string} The namespace that is used to items.
  201. * @return {Array}
  202. * @example
  203. * this._localStorageController.getAll();
  204. * this._localStorageController.getAll('myNamespace~');
  205. */
  206. public getAll(namespace:string = null):Array<any>
  207. {
  208. let list:Array<{ key:string, value:any }> = [];
  209. const length:number = this.getLength();
  210. for (let i:number = 0; i < length; i++)
  211. {
  212. let key:string = this._localStorage.key(i);
  213. let value:any = this.get(key);
  214.  
  215. list.push({
  216. key: key,
  217. value: value
  218. });
  219. }
  220.  
  221. if (namespace != null) {
  222. list = list.filter(obj => obj.key.indexOf(namespace) >= 0);
  223. }
  224.  
  225. return list;
  226. }
  227.  
  228. /**
  229. * Deletes a key/value pair from the Local Storage collection.
  230. *
  231. * @method remove
  232. * @param key {string}
  233. * @param [useNamespace=false] {string}
  234. * @return {boolean}
  235. * @example
  236. * this._localStorageController.remove('someName');
  237. *
  238. * // If you set a namespace you would pass 'true' into the second parameter.
  239. * this._localStorageController.remove('someName', true);
  240. */
  241. public remove(key:string, useNamespace:boolean = false):boolean
  242. {
  243. if (useNamespace)
  244. {
  245. key = this.getNamespace() + key;
  246. }
  247.  
  248. try
  249. {
  250. this._localStorage.removeItem(key);
  251. return true;
  252. }
  253. catch (error)
  254. {
  255. return false;
  256. }
  257. }
  258.  
  259. /**
  260. * Returns the number of items storage in local storage.
  261. *
  262. * @method getLength
  263. * @returns {number}
  264. * @example
  265. * const numberOfItemsInLocalStorage = this._localStorageController.getLength();
  266. */
  267. public getLength():number
  268. {
  269. return this._localStorage.length;
  270. }
  271.  
  272. /**
  273. * Returns the size of the Local Storage.
  274. *
  275. * @method getSize
  276. * @returns {number}
  277. * @example
  278. * const sizeOfLocalStorage = this._localStorageController.getSize();
  279. */
  280. public getSize():number
  281. {
  282. return encodeURIComponent(JSON.stringify(this._localStorage)).length;
  283. }
  284.  
  285. /**
  286. * Removes all key/value pairs from the Local Storage area.
  287. *
  288. * @method removeAll
  289. * @param [namespace=null] {string}
  290. * @example
  291. * this._localStorageController.removeAll();
  292. * this._localStorageController.removeAll('myNamespace~');
  293. */
  294. public removeAll(namespace:string = null):void
  295. {
  296. if (namespace == null) {
  297. this._localStorage.clear();
  298. } else {
  299. this._removeItemsWithNamespace(namespace);
  300. }
  301. }
  302.  
  303. /**
  304. * @method _onLocalStorageEvent
  305. * @param event {StorageEvent} The native browser event for Web Storage.
  306. * @protected
  307. */
  308. protected _onLocalStorageEvent(event:StorageEvent)
  309. {
  310. this.dispatchEvent(new LocalStorageEvent(LocalStorageEvent.STORAGE, false, false, event));
  311. }
  312.  
  313. /**
  314. * Deletes all key/value pairs with a certain namespace.
  315. *
  316. * @method removeItemsWithNamespace
  317. * @param namespace {string}
  318. * @protected
  319. */
  320. protected _removeItemsWithNamespace(namespace:string = this._namespace):void
  321. {
  322. const items = this.getAll(namespace);
  323.  
  324. items.forEach(data => {
  325. const { key } = data;
  326.  
  327. this.remove(key, false); // False because key already has the namespace in it.
  328. });
  329. }
  330.  
  331. }
  332.  
  333. export default LocalStorageService;
  334.