ngrx / store

RxJS powered state management for Angular applications, inspired by Redux
MIT License
3.9k stars 311 forks source link

[Question] Use object to create Effect dynamically? #433

Closed zacol closed 7 years ago

zacol commented 7 years ago

After a couple of months working with Redux, I see some patterns in my Effects. In my app, most of the Effects are responsible for: 1) Making a request to the backend. 2) Performing actions on success or error - show notification, open/close modal, redirect to the specific page, etc. 3) Dispatch new action on success or error.

As in the example below:

@Effect()
  getUsersRequest$: Observable<Action> = this.actions$
    .ofType(users.ActionTypes.GET_USERS_REQUEST)
    .map((action: users.GetUsersRequestAction) => action.payload)
    .switchMap((payload: any) => {
      return this.usersService.getUsers(payload)
        .do(response => {
          // Do something on success, e.g. show notification, open/close modal, redirect page, etc.
        }, error => {
          // Do something on error, e.g. show notification, open/close modal, redirect page, etc.
        })
        .map(response => new users.GetUsersSuccessAction(response.json()))
        .catch(error => of(new users.GetUsersErrorAction(catchErrorJson(error))));
    });

Since it is a common pattern, I start thinking about some way to make it more general and follow the DRY rule. Maybe, I can create a function which takes an object with API endpoint, instructions for success and errors, and use it to build Effect dynamically (instead of creating it manually). For example use the below object to create Effect from the above:

{
    endpoint: 'usersService.getUsers',
    onSuccess: {
        modal: {
            action: 'open',
            id: 'success-modal',
        },
        notification: {
            type: 'success',
            message: 'Success message',
        },
        dispatch: 'users.GetUsersSuccessAction',
    },
    onError: {
        modal: {
            action: 'open',
            id: 'error-modal',
        },
        notification: {
            type: 'error',
            message: 'Error message',
        },
        dispatch: 'users.GetUsersErrorAction',
    },
}

I now that there will be at least one Effect that will be different from the pattern and in this case I need to write it manually but this can work for most of the cases. What do you think about this idea? Do you see any cons of this solution?

robwormald commented 7 years ago

Yes, this is possible. We're migrating over to https://github.com/ngrx/platform, so I'm going to close this issue. Please use our gitter channel(s) for support / how-to questions in the future. Thanks!