nestjs / cqrs

A lightweight CQRS module for Nest framework (node.js) :balloon:
https://nestjs.com
MIT License
843 stars 150 forks source link

Saga: Responding to event by issuing multiple commands #29

Closed tschachten closed 5 years ago

tschachten commented 5 years ago

I'm submitting a...


[ ] Regression 
[ ] Bug report
[ ] Feature request
[X] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

Whenever I try to respond to an event within a saga by issuing multiple commands an error gets thrown and my application crashes. Debugging showed me that the error seems to be 'CommandHandler not found exception!', but I don't know where this error arises from - when returning just 1 command instead of multiple ones then everything is working fine.

Expected behavior

A saga can return multiple commands in response to an event.

Minimal reproduction of the problem with instructions

My saga simplified looks like this:

@Injectable()
export class SomeSagas {
    public constructor() {}

    onSomeEvent(events$: EventObservable<any>): Observable<ICommand> {
        return events$.ofType(SomeEvent).pipe(
            map((event: SomeEvent) => {
                return of(new SomeCommand(uuid()), new SomeCommand(uuid()));
            }),
        );
    }
}

What is the motivation / use case for changing the behavior?

Having a saga that is able to issue multiple commands in response to an event.

Environment


Nest version: 5.4+
CQRS version: 5.1.1


For Tooling issues:
- Node version: 10.11.0
- Platform:  Mac

Others:

tschachten commented 5 years ago

Seems like I was using it the wrong way - the following seems to be working for me:

@Injectable()
export class SomeSagas {
    public constructor() {}

    onSomeEvent(events$: EventObservable<any>): Observable<ICommand> {
        return events$.ofType(SomeEvent).pipe(
            map((event: SomeEvent) => {
                return [
                    new SomeCommand(uuid()),
                    new SomeCommand(uuid()),
                ];
            }),
            flatMap(c => c), // this is solving my issue
        );
    }
}

I'd like to suggest to add an example of that case to the example repository for guys like me that have not been working with RxJS before? IMO it's pretty common that you'll need to respond to an event by issuing multiple commands at some point.

kamilmysliwiec commented 5 years ago

Hi @tschachten, I'm glad that you found a solution :) Feel free to create a PR to the example repository, contributions are always welcome!

codemile commented 4 years ago

Just use a mergeMap next time.

mergeMap((event: SomeEvent) => of(new SomeCommand(uuid()), new SomeCommand(uuid()))),
LinboLen commented 4 years ago

how to get a req/res like event stream ?