New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@angular-architects/ngrx-toolkit

Package Overview
Dependencies
Maintainers
4
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@angular-architects/ngrx-toolkit

  • 0.0.4
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
26K
decreased by-0.87%
Maintainers
4
Weekly downloads
 
Created
Source

NgRx Toolkit

NgRx Toolkit is an extension to the NgRx Signals Store. It is still in beta but already offers following features:

  • Devtools: Integration into Redux Devtools
  • Redux: Possibility to use the Redux Pattern (Reducer, Actions, Effects)

To install it, run

npm i @angular-architects/ngrx-toolkit

Devtools: withDevtools()

This extension is very easy to use. Just add it to a signalStore. Example:

export const FlightStore = signalStore(
  { providedIn: 'root' },
  withDevtools('flights'), // <-- add this
  withState({ flights: [] as Flight[] }),
  // ...
);

Redux: withRedux()

withRedux() bring back the Redux pattern into the Signal Store.

It can be combined with any other extension of the Signal Store.

Example:

export const FlightStore = signalStore(
  { providedIn: 'root' },
  withState({ flights: [] as Flight[] }),
  withRedux({
    actions: {
      public: {
        load: payload<{ from: string; to: string }>(),
      },
      private: {
        loaded: payload<{ flights: Flight[] }>(),
      },
    },
    reducer(actions, on) {
      on(actions.loaded, ({ flights }, state) => {
        patchState(state, 'flights loaded', { flights });
      });
    },
    effects(actions, create) {
      const httpClient = inject(HttpClient);
      return {
        load$: create(actions.load).pipe(
          switchMap(({ from, to }) =>
            httpClient.get<Flight[]>(
              'https://demo.angulararchitects.io/api/flight',
              {
                params: new HttpParams().set('from', from).set('to', to),
              },
            ),
          ),
          tap((flights) => actions.loaded({ flights })),
        ),
      };
    },
  }),
);

DataService withDataService()

withDataService() allows to connect a Data Service to the store:

This gives you a store for a CRUD use case:

export const SimpleFlightBookingStore = signalStore(
  { providedIn: 'root' },
  withCallState(),
  withEntities<Flight>(),
  withDataService({
    dataServiceType: FlightService, 
    filter: { from: 'Paris', to: 'New York' },
  }),
  withUndoRedo(),
);

The features withCallState and withUndoRedo are optional, but when present, they enrich each other.

The Data Service needs to implement the DataService interface:

@Injectable({
  providedIn: 'root'
})
export class FlightService implements DataService<Flight, FlightFilter> {
  loadById(id: EntityId): Promise<Flight> { ... }
  load(filter: FlightFilter): Promise<Flight[]> { ... }

  create(entity: Flight): Promise<Flight> { ... }
  update(entity: Flight): Promise<Flight> { ... }
  delete(entity: Flight): Promise<void> { ... }
  [...]
}

Once the store is defined, it gives its consumers numerous signals and methods they just need to delegate to:

@Component(...)
export class FlightSearchSimpleComponent {
  private store = inject(SimpleFlightBookingStore);

  from = this.store.filter.from;
  to = this.store.filter.to;
  flights = this.store.entities;
  selected = this.store.selectedEntities;
  selectedIds = this.store.selectedIds;

  loading = this.store.loading;

  canUndo = this.store.canUndo;
  canRedo = this.store.canRedo;

  async search() {
    this.store.load();
  }

  undo(): void {
    this.store.undo();
  }

  redo(): void {
    this.store.redo();
  }

  updateCriteria(from: string, to: string): void {
    this.store.updateFilter({ from, to });
  }

  updateBasket(id: number, selected: boolean): void {
    this.store.updateSelected(id, selected);
  }

}

DataService with Dynamic Properties

To avoid naming conflicts, the properties set up by withDataService and the connected features can be configured in a typesafe way:

export const FlightBookingStore = signalStore(
  { providedIn: 'root' },
  withCallState({
    collection: 'flight'
  }),
  withEntities({ 
    entity: type<Flight>(), 
    collection: 'flight'
  }),
  withDataService({
    dataServiceType: FlightService, 
    filter: { from: 'Graz', to: 'Hamburg' },
    collection: 'flight'
  }),
  withUndoRedo({
    collections: ['flight'],
  }),
);

This setup makes them use flight as part of the used property names. As these implementations respect the Type Script type system, the compiler will make sure these properties are used in a typesafe way:

@Component(...)
export class FlightSearchDynamicComponent {
  private store = inject(FlightBookingStore);

  from = this.store.flightFilter.from;
  to = this.store.flightFilter.to;
  flights = this.store.flightEntities;
  selected = this.store.selectedFlightEntities;
  selectedIds = this.store.selectedFlightIds;

  loading = this.store.flightLoading;

  canUndo = this.store.canUndo;
  canRedo = this.store.canRedo;

  async search() {
    this.store.loadFlightEntities();
  }

  undo(): void {
    this.store.undo();
  }

  redo(): void {
    this.store.redo();
  }

  updateCriteria(from: string, to: string): void {
    this.store.updateFlightFilter({ from, to });
  }

  updateBasket(id: number, selected: boolean): void {
    this.store.updateSelectedFlightEntities(id, selected);
  }

}

FAQs

Package last updated on 09 Feb 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc