Efficientclient-sidestoragemoduleforAngular:
simplicity:simpleAPIlikenativelocalStorage,perfomance:internallystoredviatheasynchronousindexedDBAPI,Angular-like:wrappedinRxJSObservables,security:validatedatawithaJSONSchema,compatibility:worksaroundsomebrowsersissuesandheavilytestedviaGitHubActions,documentation:APIfullyexplained,andachangelog!SponsorshipYoulikethislibrarydownloadedmorethan15000timeseachweekonnpm?Youliketheseriousopensourcework(fulldocumentation,libreadyondayoneofAngularmajorupdates,...)?Andyourcompanyisusingitinprojectsgeneratingmoney?
Well,onmyside,it'salotofunpaidwork.Sopleaseconsider:
becomingaregularsponsordoingaone-timedonationatleast,taking2minutestoshowyourloveBythesameauthorAngularschematicsextensionforVSCode(GUIforAngularCLIcommands)typescript-strictly-typed:reliablecodewithTypeScriptstrictlytypedPopularAngularpostsonMediumFollowupdatesofthislibonTwitterAngulartrainings(inFrench,asI'mbasedinParis,butmyEnglishbioishereanditcanbedoneremotely)Whythismodule?Fornow,Angulardoesnotprovideaclient-sidestoragemodule,andalmosteveryappneedssomeclient-sidestorage.Thereare2nativeJavaScriptAPIsavailable:
localStorageindexedDBThelocalStorageAPIissimpletousebutsynchronous,soifyouuseittoooften,yourappwillsoonbegintofreeze.
TheindexedDBAPIisasynchronousandefficient,butit'samesstouse:you'llsoonbecaughtbythecallbackhell,asitdoesnotsupportPromisesyet.
MozillahasdoneaverygreatjobwiththelocalForagelibrary:asimpleAPIbasedonnativelocalStorage,butinternallystoredviatheasynchronousindexedDBforperformance.Butit'sbuiltinES5oldschoolwayandthenit'samesstoincludeintoAngular.
ThismoduleisbasedonthesameideaaslocalForage,butbuiltinES6+andadditionallywrappedintoRxJSObservablestobehomogeneouswithotherAngularmodules.
GettingstartedInstallthepackage,accordingtoyourAngularversion:
#ForAngularLTS(Angular>=10):ngadd@ngx-pwa/local-storageDone!
Youshouldsticktothesecommands.Ifforanyreasonngadddoesnotwork,besuretofollowthemanualinstallationguide,asthereareadditionnalstepstodoinadditiontothepackageinstallationforsomeversions.
Ifyouhavemultipleapplicationsinthesameproject,asusual,youneedtochoosetheproject:
ngadd@ngx-pwa/local-storage--projectyourprojectnameUpgradingToupdatetonewversions,seethemigrationguides.
APIimport{StorageMap}from'@ngx-pwa/local-storage';@Injectable()exportclassYourService{constructor(privatestorage:StorageMap){}}ThisserviceAPIfollowsthenewstandardkv-storageAPI,whichissimilartothestandardMapAPI,andclosetothestandardlocalStorageAPI,exceptit'sbasedonRxJSObservablesinsteadofPromises:
classStorageMap{//Writeset(index:string,value:any):Observable<undefined>{}delete(index:string):Observable<undefined>{}clear():Observable<undefined>{}//Read(one-time)get(index:string):Observable<unknown>{}get<T>(index:string,schema:JSONSchema):Observable<T>{}//Observewatch(index:string):Observable<unknown>{}watch<T>(index:string,schema:JSONSchema):Observable<T>{}//Advancedsize:Observable<number>;has(index:string):Observable<boolean>{}keys():Observable<string>{}}Note:thereisalsoaLocalStorageserviceavailable,butonlyforcompatibilitywitholdversionsofthislib.
HowtoWritingdataletuser:User={firstName:'Henri',lastName:'Bergson'};this.storage.set('user',user).subscribe(()=>{});Youcanstoreanyvalue,withoutworryingaboutserializing.Butnotethat:
storingnullorundefinedmakesnosenseandcancauseissuesinsomebrowsers,sotheitemwillberemovedinstead,youshouldsticktoJSONdata,ie.primitivetypes,arraysandliteralobjects.Date,Map,Set,Blobandotherspecialstructurescancauseissuesinsomescenarios.Seetheserializationguideformoredetails.DeletingdataTodeleteoneitem:
this.storage.delete('user').subscribe(()=>{});Todeleteallitems:
this.storage.clear().subscribe(()=>{});ReadingdataTogetthecurrentvalue:
this.storage.get('user').subscribe((user)=>{console.log(user);});Notfindinganitemisnotanerror,itsucceedsbutreturnsundefined:
this.storage.get('notexisting').subscribe((data)=>{data;//undefined});Noteyouwillonlygetonevalue:theObservableishereforasynchronybutisnotmeanttoemitagainwhenthestoreddataischanged.Ifyouneedtowatchthevalue,seethewatchingguide.
CheckingdataDon'tforgetit'sclient-sidestorage:alwayscheckthedata,asitcouldhavebeenforged.
YoucanuseaJSONSchematovalidatethedata.
this.storage.get('test',{type:'string'}).subscribe({next:(user)=>{/*Calledifdataisvalidor`undefined`*/},error:(error)=>{/*Calledifdataisinvalid*/},});Seethefullvalidationguidetoseehowtovalidateallcommonscenarios.
SubscriptionYouDONOTneedtounsubscribe:theObservableautocompletes(likeintheAngularHttpClientservice).
ButyouDOneedtosubscribe,evenifyoudon'thavesomethingspecifictodoafterwritinginstorage(becauseit'showRxJSObservableswork).
ErrorsAsusual,it'sbettertocatchanypotentialerror:
this.storage.set('color','red').subscribe({next:()=>{},error:(error)=>{},});Forreadoperations,youcanalsomanageerrorsbyprovidingadefaultvalue:
import{of}from'rxjs';import{catchError}from'rxjs/operators';this.storage.get('color').pipe(catchError(()=>of('red')),).subscribe((result)=>{});Seetheerrorsguideforsomedetailsaboutwhaterrorscanhappen.
ExpirationThislib,asnativelocalStorageandindexedDb,isaboutpersistentstorage.
Wantingtemporarystorage(likesessionStorage)isaverycommonmisconception:anapplicationdoesn'tneedthat.Moredetailshere.
Map-likeoperationsInadditiontotheclassiclocalStorage-likeAPI,thislibalsoprovidesaMap-likeAPIforadvancedoperations:
.keys().has(key).sizeSeethedocumentationformoreinfoandsomerecipes.Forexample,itallowstoimplementamultipledatabasesscenario.
SupportAngularsupportWefollowAngularLTSsupport.
ThismodulesupportsUniversalserver-siderenderingviaamockstorage.
BrowsersupportThislibsupportsthesamebrowsersasAngular.Seethebrowserssupportguideformoredetailsandspecialcases(likeprivatebrowsing).
CollisionIfyouhavemultipleappsonthesamesubdomainandyoudon'twanttosharedatabetweenthem,seetheprefixguide.
InteroperabilityForinteroperabilitywhenmixingthislibwithdirectusageofnativeAPIsorotherlibslikelocalForage(whichdoesn'tmakesenseinmostcases),seetheinteroperabilitydocumentation.
ChangelogChangelogavailablehere,andmigrationguideshere.
LicenseMIT
评论