JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2
  • Score
    100M100P100Q55403F
  • License MIT

NgRx Plugin for Boilerplate Elimination

Package Exports

  • ngrx-handlers

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (ngrx-handlers) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

πŸ•ΉοΈ NgRx Handlers

MIT License NPM Build Status Coverage Status Code Grade Downloads

NgRx Plugin for Boilerplate Elimination

☝️ Why to use NgRx Handlers?

  • Because it's boring to write action types manually
  • Because it's annoying to define an action and then its case reducer every single time
  • Because you don't need to write too much code for simple functionality
  • Because unlike other boilerplate-free plugins, NgRx Handlers keep NgRx look and feel

πŸš€ Getting Started

πŸ”§ Installation

NPM: npm install ngrx-handlers

Yarn: yarn add ngrx-handlers

⚑ Usage

NgRx Boilerplate

// books.actions.ts

import { createAction, props } from '@ngrx/store';
import { Book } from '../models/book';

export const fetchBooks = createAction('[Books] Fetch Books');
export const fetchBooksSuccess = createAction(
  '[Books] Fetch Books Success',
  props<{ books: Book[] }>(),
);
export const fetchBooksError = createAction('[Books] Fetch Books Error');

export const updateSearchTerm = createAction(
  '[Books] Update Search Term',
  props<{ searchTerm: string }>(),
);

// books.reducer.ts

import { Book } from '../models/book';
import { createReducer, on } from '@ngrx/store';
import * as BooksActions from './books.actions';

export const featureName = 'books';

export interface State {
  books: Book[];
  loading: boolean;
  searchTerm: string;
}

export const initialState: State = {
  books: [],
  loading: false,
  searchTerm: '',
};

export const reducer = createReducer(
  initialState,
  on(BooksActions.fetchBooks, state => ({ ...state, loading: true })),
  on(BooksActions.fetchBooksSuccess, (state, { books }) => ({ ...state, books, loading: false })),
  on(BooksActions.fetchBooksError, state => ({ ...state, books: [], loading: false })),
  on(BooksActions.updateSearchTerm, (state, { searchTerm }) => ({ ...state, searchTerm })),
);

NgRx Handlers

// books.handlers.ts

import { Book } from '../models/book';
import { combineHandlers } from 'ngrx-handlers';

export const featureName = 'books';

export interface State {
  books: Book[];
  loading: boolean;
  searchTerm: string;
}

export const initialState: State = {
  books: [],
  loading: false,
  searchTerm: '',
};

export const { actions, reducer } = combineHandlers(initialState, featureName, {
  fetchBooks: state => ({ ...state, loading: true }),
  fetchBooksSuccess: (state, { books }: { books: Book[] }) => ({ ...state, books, loading: false }),
  fetchBooksError: state => ({ ...state, books: [], loading: false }),
  updateSearchTerm: (state, { searchTerm }: { searchTerm: string }) => ({ ...state, searchTerm }),
});

combineHandlers function returns strongly typed action creators and a reducer with O(1) efficiency.

Another great thing about combineHandlers is that you don't have to manually write action types. For example, when the feature name is books and the action name is fetchBooks, it will generate the action creator with type [Books] Fetch Books.

In case you need to define actions without changing the state, this plugin provides plain and withPayload functions.

export const { actions, reducer } = combineHandlers(initialState, featureName, {
  showCreateBookDialog: plain(),
  createBook: withPayload<{ book: Book }>(),
});

See the sample project here.

✊ Show Your Support

Give a ⭐ if you like NgRx Handlers πŸ™‚

🀝 Contribute

Contributions are always welcome!

πŸ’‘ Inspiration

This project is inspired by Juliette.

πŸ“ License

This project is MIT licensed.

Copyright © 2020 Marko Stanimirović