From 1ced35a62c61d9a3a53a1a7a8e0887353f59135b Mon Sep 17 00:00:00 2001 From: Jay Phelps Date: Tue, 19 Sep 2017 13:03:01 -0700 Subject: [PATCH 1/4] docs(effects): Remove usage of deprecated `toPayload` util in example (#407) --- docs/effects/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/effects/README.md b/docs/effects/README.md index 68f9280271..78bf92ad54 100644 --- a/docs/effects/README.md +++ b/docs/effects/README.md @@ -46,17 +46,15 @@ import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import { Action } from '@ngrx/store'; -import { Actions, Effect, toPayload } from '@ngrx/effects'; +import { Actions, Effect } from '@ngrx/effects'; import { of } from 'rxjs/observable/of'; @Injectable() export class AuthEffects { // Listen for the 'LOGIN' action @Effect() login$: Observable = this.actions$.ofType('LOGIN') - // Map the payload into JSON to use as the request body - .map(toPayload) - .mergeMap(payload => - this.http.post('/auth', payload) + .mergeMap(action => + this.http.post('/auth', action.payload) // If successful, dispatch success action with result .map(data => ({ type: 'LOGIN_SUCCESS', payload: data })) // If request fails, dispatch failed action From 193e8b39022d8baf59d5e8312c4255aed96f76dc Mon Sep 17 00:00:00 2001 From: Stan Carrico Date: Tue, 19 Sep 2017 18:05:35 -0700 Subject: [PATCH 2/4] fix(Example): Add missing import for catch operator (#409) --- docs/effects/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/effects/README.md b/docs/effects/README.md index 78bf92ad54..3bfe823cac 100644 --- a/docs/effects/README.md +++ b/docs/effects/README.md @@ -42,6 +42,7 @@ want to use to perform a side effect. // ./effects/auth.ts import 'rxjs/add/operator/map'; import 'rxjs/add/operator/mergeMap'; +import 'rxjs/add/operator/catch'; import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import { Observable } from 'rxjs/Observable'; From 2afb792060f496262b77ec64ea39088bef2c409e Mon Sep 17 00:00:00 2001 From: Phill Z Date: Wed, 20 Sep 2017 11:19:33 +1000 Subject: [PATCH 3/4] feat(Entity): Add default selectId function for EntityAdapter (#405) --- modules/entity/src/create_adapter.ts | 11 +++++++---- modules/store/src/store_module.ts | 8 ++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/modules/entity/src/create_adapter.ts b/modules/entity/src/create_adapter.ts index 0526ccf692..c51f85295f 100644 --- a/modules/entity/src/create_adapter.ts +++ b/modules/entity/src/create_adapter.ts @@ -10,12 +10,15 @@ import { createSelectorsFactory } from './state_selectors'; import { createSortedStateAdapter } from './sorted_state_adapter'; import { createUnsortedStateAdapter } from './unsorted_state_adapter'; -export function createEntityAdapter(options: { - selectId: IdSelector; - sortComparer?: false | Comparer; -}): EntityAdapter { +export function createEntityAdapter( + options: { + selectId?: IdSelector; + sortComparer?: false | Comparer; + } = {} +): EntityAdapter { const { selectId, sortComparer }: EntityDefinition = { sortComparer: false, + selectId: (instance: any) => instance.id, ...options, }; diff --git a/modules/store/src/store_module.ts b/modules/store/src/store_module.ts index c6f3abbc95..804c70c6bb 100644 --- a/modules/store/src/store_module.ts +++ b/modules/store/src/store_module.ts @@ -149,12 +149,16 @@ export class StoreModule { ): ModuleWithProviders; static forFeature( featureName: string, - reducer: ActionReducer| InjectionToken>, + reducer: ActionReducer | InjectionToken>, config?: StoreConfig ): ModuleWithProviders; static forFeature( featureName: string, - reducers: ActionReducerMap | InjectionToken> | ActionReducer | InjectionToken>, + reducers: + | ActionReducerMap + | InjectionToken> + | ActionReducer + | InjectionToken>, config: StoreConfig = {} ): ModuleWithProviders { return { From ddb2f9730cc01658f5cd2b551618baa1f01d6338 Mon Sep 17 00:00:00 2001 From: Brandon Date: Wed, 20 Sep 2017 13:15:05 -0500 Subject: [PATCH 4/4] docs(Entity): Fix examples for @ngrx/entity usage (#415) Closes #399, #403, #412, #413 --- CONTRIBUTING.md | 11 -------- docs/entity/adapter.md | 55 ++++++++++++++++++++------------------- docs/entity/interfaces.md | 26 ++++++++++-------- docs/store/api.md | 2 +- 4 files changed, 44 insertions(+), 50 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 915a5e3e8d..af11b08c42 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,23 +2,12 @@ ### Setup -``` -npm install -``` - -OR ``` yarn ``` ### Testing -``` -npm test -``` - -OR - ``` yarn test ``` diff --git a/docs/entity/adapter.md b/docs/entity/adapter.md index f2bf430dd3..c64729083e 100644 --- a/docs/entity/adapter.md +++ b/docs/entity/adapter.md @@ -15,9 +15,8 @@ Usage: import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity'; export interface User { - id: number; + id: string; name: string; - description: string; } export interface State extends EntityState { @@ -30,7 +29,6 @@ export function sortByName(a: User, b: User): number { } export const adapter: EntityAdapter = createEntityAdapter({ - selectId: (user: User) => user.id, sortComparer: sortByName, }); ``` @@ -38,7 +36,7 @@ export const adapter: EntityAdapter = createEntityAdapter({ ## Adapter Methods These methods are provided by the adapter object returned -when using [createEntityAdapter](#createEntityAdapter). The methods are used inside your reducer function to manage +when using [createEntityAdapter](#createentityadapter). The methods are used inside your reducer function to manage the entity collection based on your provided actions. ### getInitialState @@ -51,9 +49,8 @@ Usage: import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity'; export interface User { - id: number; + id: string; name: string; - description: string; } export interface State extends EntityState { @@ -96,9 +93,8 @@ Usage: ```ts export interface User { - id: number; + id: string; name: string; - description: string; } ``` @@ -138,25 +134,25 @@ export class AddUsers implements Action { export class UpdateUser implements Action { readonly type = UPDATE_USER; - constructor(public payload: { user: User }) {} + constructor(public payload: { user: { id: string, changes: User } }) {} } export class UpdateUsers implements Action { readonly type = UPDATE_USERS; - constructor(public payload: { users: User[] }) {} + constructor(public payload: { users: { id: string, changes: User }[] }) {} } export class DeleteUser implements Action { readonly type = DELETE_USER; - constructor(public payload: { user: User }) {} + constructor(public payload: { id: string }) {} } export class DeleteUsers implements Action { readonly type = DELETE_USERS; - constructor(public payload: { users: User[] }) {} + constructor(public payload: { ids: string[] }) {} } export class ClearUsers implements Action { @@ -185,9 +181,7 @@ export interface State extends EntityState { selectedUserId: number | null; } -export const adapter: EntityAdapter = createEntityAdapter({ - selectId: (user: User) => user.id -}); +export const adapter: EntityAdapter = createEntityAdapter(); export const initialState: State = adapter.getInitialState({ // additional entity state properties @@ -215,6 +209,14 @@ export function reducer( return adapter.updateMany(action.payload.users, state); } + case UserActions.DELETE_USER: { + return adapter.removeOne(action.payload.id, state); + } + + case UserActions.DELETE_USERS: { + return adapter.removeMany(action.payload.ids, state); + } + case UserActions.LOAD_USERS: { return adapter.addAll(action.payload.users, state); } @@ -236,41 +238,40 @@ export const getSelectedUserId = (state: State) => state.selectedUserId; The `getSelectors` method returned by the created entity adapter provides functions for selecting information from the entity. -The `getSelectors` method takes a selector function -as its only argument to select the piece of state for a defined entity. +The `getSelectors` method takes a selector function as its only argument to select the piece of state for a defined entity. Usage: `reducers/index.ts` ```ts -import { createSelector, createFeatureSelector } from '@ngrx/store'; +import { createSelector, createFeatureSelector, ActionReducerMap } from '@ngrx/store'; import * as fromUser from './user.reducer'; export interface State { users: fromUser.State; } -export const selectUserState = createFeatureSelector('users'); +export const reducers: ActionReducerMap = { + users: fromUser.reducer +}; + +export const selectUserState = createFeatureSelector('users'); export const { // select the array of user ids - selectIds: getUserIds, + selectIds: selectUserIds, // select the dictionary of user entities - selectEntities: getUserEntities, + selectEntities: selectUserEntities, // select the array of users - selectAll: getAllUsers, + selectAll: selectAllUsers, // select the total user count - selectTotal: getUserTotal + selectTotal: selectUserTotal } = fromUser.adapter.getSelectors(selectUserState); -export const selectUserIds = createSelector(selectUserState, getUserIds); -export const selectUserEntities = createSelector(selectUserState, getUserEntities); -export const selectAllUsers = createSelector(selectUserState, getAllUsers); -export const selectUserCount = createSelector(selectUserState, getUserTotal); export const selectCurrentUserId = createSelector(selectUserState, fromUser.getSelectedUserId); export const selectCurrentUser = createSelector( selectUserEntities, diff --git a/docs/entity/interfaces.md b/docs/entity/interfaces.md index 9a618dd771..ba4a3566e0 100644 --- a/docs/entity/interfaces.md +++ b/docs/entity/interfaces.md @@ -2,20 +2,26 @@ ## EntityState -The Entity State is a predefined generic interface for a given entity collection with the following properties: +The Entity State is a predefined generic interface for a given entity collection with the following interface: - * `ids`: An array of all the primary ids in the collection - * `entities`: A dictionary of entities in the collection indexed by the primary id +```ts +interface EntityState { + ids: string[]; + entities: { [id: string]: V }; +} +``` - Extend this interface to provided any additional properties for the entity state. +* `ids`: An array of all the primary ids in the collection +* `entities`: A dictionary of entities in the collection indexed by the primary id - Usage: +Extend this interface to provided any additional properties for the entity state. - ```ts +Usage: + +```ts export interface User { - id: number; + id: string; name: string; - description: string; } export interface State extends EntityState { @@ -31,7 +37,5 @@ Provides a generic type interface for the provided [entity adapter](./adapter.md Usage: ```ts -export const adapter: EntityAdapter = createEntityAdapter({ - selectId: (user: User) => user.id -}); +export const adapter: EntityAdapter = createEntityAdapter(); ``` diff --git a/docs/store/api.md b/docs/store/api.md index 0e99c3b53a..53b39087d6 100644 --- a/docs/store/api.md +++ b/docs/store/api.md @@ -167,7 +167,7 @@ To inject meta reducers, use the `META_REDUCERS` injection token exported in the Store API and a `Provider` to register the meta reducers through dependency injection. -``` +```ts import { MetaReducer, META_REDUCERS } '@ngrx/store'; import { SomeService } from './some.service';