ngneat / forms-manager

🦄 The Foundation for Proper Form Management in Angular
https://www.netbasal.com
MIT License
518 stars 29 forks source link

feat(forms-manager): add support for session storage #32

Closed nickhh76 closed 2 years ago

nickhh76 commented 2 years ago

Adds ability to use session storage for persistence, configurable through NgFormsManagerConfig

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

[ ] Bugfix
[X] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

Currently, when persistState is set to true in UpsertConfig, state is always persisted to local storage.

Issue Number: N/A

What is the new behavior?

Through configuration using the NG_FORMS_MANAGER_CONFIG token, the user can now choose to use session storage instead. Projects using the library that don't use the new configuration option will continue to use local storage by default.

Configuration example:

import { NG_FORMS_MANAGER_CONFIG, NgFormsManagerConfig } from '@ngneat/forms-manager';

@NgModule({
  declarations: [AppComponent],
  imports: [ReactiveFormsModule],
  providers: [
    {
      provide: NG_FORMS_MANAGER_CONFIG,
      useValue: new NgFormsManagerConfig({
        storage: {
          type: 'SessionStorage', // accepts 'LocalStorage' or 'SessionStorage', can be omitted to default to local storage
          key: 'myCustomKey',
        },
      }),
    },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Does this PR introduce a breaking change?

[ ] Yes
[X] No

Other information

This provides a simple solution to the common requirement of having to delete any user data when the browser session closes. This solution is backward-compatible, requires minimal configuration and is fully tested and documented.

NetanelBasal commented 2 years ago

Thanks for the PR. I'm wondering why not use one token:

export const FORMS_MANAGER_STORAGE = new InjectionToken<Storage | undefined>('FORMS_MANAGER_STORAGE', {
  providedIn: 'root',
  factory: () => (isPlatformBrowser(inject(PLATFORM_ID)) ? localStorage : undefined),
});

Now if someone wants to use sessionStorage they can define it as follows:

{
  provide: FORMS_MANAGER_STORAGE,
  useValue: sessionStorage
}

We can also export it from the library:

export const FORMS_MANAGER_SESSION_STORAGE = {
  provide: FORMS_MANAGER_STORAGE,
  ....
}
nickhh76 commented 2 years ago

Thanks for your feedback! I agree with your suggested approach. It's simpler and more flexible.

I have updated the PR accordingly. Please let me know if you have any further comments.

Thanks, Nick