-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Add ability to create functional effects #3668
Comments
I love it for two reasons:
|
Is it possible to make the first argument for the callback function the injected
Of course I think the users themselves will be able to do this manually, but would be nice to have. Other than this. absolutely love the idea, removes boilerplate, removes ambiguity, also easier to explain in general I think |
This is cool ,I can't wait |
It's such a nice idea. I'm just curious whether it's possible to have two effects in two different files which share the same name, like this // foo.effects.ts
export const fooBarEffect = createEffect(() => {
// ...
});
// more effects
// bar.effects.ts
export const fooBarEffect = createEffect(() => {
// ...
});
// more effects import * as fooEffects from './foo.effects.ts';
import * as barEffects from './bar.effects.ts';
bootstrapApplication(AppComponent, {
providers: [
provideEffects(fooEffects, barEffects),
],
}); |
That's very nice! |
@stefanoslig yes that will still be possible. Being able to use effects in a class isn't changing at all. |
@phhien203 yes, that would be possible. |
Thank @timdeschryver |
RFC description updated ☝️ |
I'd rather not provide (actions$ = inject(Actions)) => actions$.pipe(/* ... */)
// or
() => inject(Actions).pipe(/* ... */) compared to: (actions$) => actions$.pipe(/* ... */); while the first option gives more flexibility. |
@markostanimirovic I get you idea. How about a factory function that allows creating predefined effect creator functions? Like this: const createUserEffects = createEffectFactory([Actions, UserService, SomeOtherService]);
const loadUsers = createUserEffects((actions, userService, someOtherService) => {
return actions.pipe(
ofType(someAction);
// and so on
);
}) Just feels kinda neater. In testing, we can still provide whatever mock values we want by calling it with mock args, can we? I think we should be able to do that |
Reminds me of angularjs 🤕 |
@liesahead how come? We use factories in Angular and also in NgRx all the time. We have selector factory functions, for example. This is not a separate configuration, but a factory function to return a preconfigured effect creator |
But in each effect you would need to inject all services as function arguments |
@liesahead const createUserEffects = createEffectFactory({
actions$: Actions,
userService: UserService,
someOtherService: SomeOtherService,
});
const loadUsers = createUserEffects({actions, userService}) => {
// use only the services you need for a particular effect
return actions.pipe(
ofType(someAction);
// and so on
);
}) |
@Armenvardanyan95 , this one I like more 😄 anyway, if this doesn't replace current behavior (with services injection in the constructor) and comes as an additional feature then I think it might be a good idea for some people. |
my code coverage is nagging about uncovered branches regarding the injected dependecies, any clew how to mitigate that?
|
Did you solve this? I have the exact problem atm |
Yes, you can use the it('should return loadMecListSuccess action, with the list, on success', () => {
const mecList: Mec[] = [{} as Mec];
const action = Actions.initCommandeManagement();
actions$ = of(action);
mecListServiceMock.loadMECsNonPagine.mockReturnValue(of(mecList));
expect(TestBed.runInInjectionContext(Effects.loadMecList$)).subscribe((resultAction) => {
expect(mecListService.loadMECsNonPagine).toHaveBeenCalled();
expect(resultAction).toEqual(
Actions.loadMecListSuccess({
mecList,
}),
);
});
}); Note that you have to use the |
Thanks! |
Which @ngrx/* package(s) are relevant/related to the feature request?
effects
Information
Add the ability to create functional effects (without classes). Similar to functional guards, we would be able to use
inject
within thecreateEffect
function:In order not to break the current behavior of the
createEffect
function, for functional effects we need to addfunctional: true
in the effect config. They can be registered as follows:Testing
To test functional effects, we don't need
TestBed
to provide services if we inject all dependencies as effect factory parameters (seeloadUsers
effect above). Unit test for this effect can look like this:This feature will not remove the ability to create effects within classes
We'll be still able to define effects within classes:
and register them via
provideEffects
(orEffectsModule.forRoot/forFeature
):I would be willing to submit a PR to fix this issue
The text was updated successfully, but these errors were encountered: