JSPM

  • Created
  • Published
  • Downloads 262
  • Score
    100M100P100Q119652F
  • License MIT

Package Exports

  • @gernsdorfer/ngrx-lite
  • @gernsdorfer/ngrx-lite/package.json
  • @gernsdorfer/ngrx-lite/testing

Readme

NgrxLite

A small angular State Mangement based on ngrx component-store, with some benefits 😎

Why we need this ?

The current @ngrx/component-store implementation works with its own isolated Store. Unfortunately, there is no connection to the global @ngrx/Store or the @ngrx/store-devtools.

This Library connects your @ngrx/component-store with the @ngrx/Store to share and debug the @ngrx/actions and store.

Benefits

  • 🤝 same API like @ngrx/component-store with optional parameters
  • ⏱ create fast and easy a dynamic redux store
  • ⏳ optional integrated loading state for effects
  • ⚒️ Support Redux Devtools for your light components-store (only if you use redux-devtools) for
    • patchState
    • setState
    • created effects
  • 💽 support session/locale Storage
  • 🏘 You Decide where your Store lives: Root, Module or in the Component Scope
  • 🔛 Shared your State Changes and Actions in the ngrx Store

Build Status styled with prettier PRs Publish to NPM

Open in StackBlitz

Install

yarn: yarn add @ngrx/store @gernsdorfer/ngrx-lite

npm: npm install @ngrx/store @gernsdorfer/ngrx-lite

Usage

  1. Import StoreModulefrom ngrx to your root Module
@NgModule({
  //...
  imports: [StoreModule.forRoot({})]
//...
  1. Create Your Store

You have the same API as @ngrx/component-store

export interface MyState {
  counter: number
}

@Component({
  selector: 'my-component',
  template: '<button (click)="load(\'test\')">',
})
class MyComponent implements OnDestroy {
  // create a componentStore
  private store = this.storeFactory.createComponentStore<MyState>({
    storeName: 'BASIC_COUNTER',
    defaultState: {counter: 0},
  });
  // read the state
  public counterState$: Observable<MyState> = this.store.state$;

  constructor(private storeFactory: StoreFactory) {
  }

  increment(counter: number) {
    // patch your state
    this.store.patchState({counter});
  }

  ngOnDestroy() {
    // destory the store
    this.store.ngOnDestroy();
  }
}

That's it 🥳

Features

Devtool support

Install and import ngrx/store-devtools und have all Features from the devtools for your component store

Let's have a look into the the redux devtools whats going on, in the example above.

Store is init

After the store is init you can find the store in the @ngrx/devtools

State-Init

Patch State

After patch State you see this in your redux devtool. It's possbile to define an custom Actionname for your patch/set State

State-Init

Loading Store

Create LoaderStore to set a Loader State while an Effect is running. You have the same API as createComponentStore with an extra methode loadingEffect

type State = LoadingStoreState<{ counter: number }, { message: string }>;

@Component({
  selector: 'my-app-basic-app',
  templateUrl: 'loading-effect.html',
})
export class LoadingEffectComponent implements OnDestroy {
  // create your loading store 
  private store = this.storeFactory.createComponentLoadingStore<State['item'],
    State['error']>({
    storeName: 'LOADING_STORE',
  });

  // read the state
  public counterState$: Observable<State> = this.store.state$;

  // define your loadingEffect to change the state
  public increment = this.store.loadingEffect(
    'increment',
    (counter: number = 0) => of(counter + 1)
  );

  constructor(private storeFactory: StoreFactory) {
  }

  ngOnDestroy() {
    // destory the store
    this.counterStore.ngOnDestroy();
  }
}

What's going on ? Let's have a look into the the redux devtools

Store is init

After the store is init you can find the store in the @ngrx/devtools

State-Init

Loader State isloading changed

For a running Effect isLoading is true and you can show a spinner in your UI.

State-Loading

Effect run successfully

After an Effect run Successfully the item key is updated

State-Success

Effect run unsuccessfully

After an Effect run unsuccessfully the error key contains the error

State-Success

Session/Local Storage

Register Session/Locale-Storage Service

  1. Register Session/Locale-Storage in your Root-Module
@NgModule({
  // ...
  providers: [
    {provide: SessionStoragePlugin, useValue: sessionStoragePlugin},
    {provide: LocalStoragePlugin, useValue: localStoragePlugin}
  ]
  // ...
})
  1. Create your new Store with a session Storage Sync Option
class MyLCass {
  private store = this.storeFactory.createComponentStore<{ counter: number }>({
    storeName: 'SESSION_COUNTER',
    defaultState: {
      counter: 0,
    },
    plugins: {
      storage: 'sessionStoragePlugin',
    },
  });
}

Testing

Import storeTestingFactory and write your test's. A minimal Example you can find here

All Demo Unit Test's you can find here:Open in StackBlitz

TestBed.configureTestingModule({
  //...
  providers: [storeTestingFactory()],
  //..
});