Skip to content

feat(effects-ng): Directive effects #41

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

Merged
merged 1 commit into from
Mar 3, 2023
Merged

Conversation

EricPoul
Copy link
Collaborator

@EricPoul EricPoul commented Feb 24, 2023

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

[ ] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Build related changes
[ ] CI related changes
[ ] Documentation content changes
[ ] Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

[ ] Yes
[x] No

Other information

@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@EricPoul
Copy link
Collaborator Author

EricPoul commented Feb 24, 2023

That's the implementation. What do you think about it @NetanelBasal? It seems to be a little strange, and unusual, maybe because of the new API.

@NetanelBasal
Copy link
Member

Yes, that's exactly what I meant.

@EricPoul
Copy link
Collaborator Author

EricPoul commented Mar 1, 2023

Faced with new and new corner cases. But this implementation should cover everything.

@NetanelBasal
Copy link
Member

NetanelBasal commented Mar 1, 2023

@EricPoul, I'm trying to understand the use cases you're trying to handle.

Let's say I have an effect named TodosEffects. It doesn't matter where I register it. I want to have one subscription.

Cases:

root - TodosEffects - subscribe here


root - TodosEffects - subscribe here
env injector - TodosEffects
useDirectiveEffects- TodosEffects


env injector - TodosEffects - subscribe here
useDirectiveEffects- TodosEffects


root - TodosEffects - subscribe here
useDirectiveEffects- TodosEffects


useDirectiveEffects- TodosEffects - subscribe here

What am I missing?

@EricPoul
Copy link
Collaborator Author

EricPoul commented Mar 1, 2023

TodoComponent(instance 1) - useDirectiveEffects - TodosEffects(instance 1) - subscribe here
TodoComponent(instance 2) - useDirectiveEffects - TodosEffects(instance 2) - skip subscribing

TodoComponent(instance 1).onDestory() - effects of TodosEffects(instance 1) should still be alive
TodoComponent(instance 2).onDestory() - we need to unsubscribe from the effects of TodosEffects(instance 1) but TodosEffects(instance 2) doesn't have it so we need to the effects of TodosEffects(instance 1).

Although TodosEffects(instance 1) and TodosEffects(instance 2) has the same names of effects, effects themself are different and have different references.

@NetanelBasal
Copy link
Member

but why do we care about references? The suggestion was to unique it based on the constructor name + the effect prop name. TodosEffect/getTodos

@EricPoul
Copy link
Collaborator Author

EricPoul commented Mar 1, 2023

EffectsManager.effects is a WeakMap so if I want to unsubscribe from the effect I need to pass the exact ref of the effect to the EffectsManager.removeEffects(...).

@NetanelBasal
Copy link
Member

And that will stay. We will have a global Set that registers the unique identifiers. Before registering an effect, you will check if it exists in the Set. if that's the case, skip it.

@EricPoul
Copy link
Collaborator Author

EricPoul commented Mar 1, 2023

It's what I do.

TodoComponent(instance 1) - useDirectiveEffects - TodosEffects(instance 1) - subscribe here
TodoComponent(instance 2) - useDirectiveEffects - TodosEffects(instance 2) - I skip subscription here
TodoComponent(instance 3) - useDirectiveEffects - TodosEffects(instance 3) - I skip subscription here

TodoComponent(instance 1) was destroyed - effects of TodosEffects(instance 1) should still be alive because TodoComponent(instance 2) and TodoComponent(instance 3) are still alive.

TodoComponent(instance 3) was destroyed - effects of TodosEffects(instance 1) should still be alive because TodoComponent(instance 2) is still alive.

TodoComponent(instance 2) was destroyed - effects of TodosEffects(instance 1) should be removed.
Only one way to unsubscribe from the effects of TodosEffects(instance 1) is to have them stored somewhere(what I do now)(because TodosEffects(instance 1) has already been destroyed).
Also, I have to know that the last instance of TodosEffects was destroyed, and for that, I store sources amount.

@EricPoul
Copy link
Collaborator Author

EricPoul commented Mar 1, 2023

The problem that I described is only with components and their chaotic order of being destroyed. For provideEffect a plain Set with a unique id will be enough but for components effects, it's not.

@NetanelBasal
Copy link
Member

NetanelBasal commented Mar 1, 2023

I see, but that's not the purpose of the feature as I see it. It should be only for development and should immediately throw when seeing that you try to use the same effect multiple times. We don't need to manage subscriptions.

I think it's a bad design if someone gets to the case you described.

@NetanelBasal
Copy link
Member

We help by saying "Hi, you're registering the same effect multiple times. That's not a good thing to do"

@NetanelBasal
Copy link
Member

But you're the consumer of the library. If you think we should leave your implementation, let it be.

@NetanelBasal
Copy link
Member

Let's leave your code. You already wrote it. I'd just add a test for the exact scenario you describe here

@EricPoul
Copy link
Collaborator Author

EricPoul commented Mar 1, 2023

I really don't know how is better😄
It'll be confusing if provideEffects do not subscribe twice and useDirectiveEffects does.

@NetanelBasal
Copy link
Member

useDirectiveEffects should be the same as provideEffects.

Copy link
Member

@NetanelBasal NetanelBasal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work. We just need to update the docs.

@EricPoul
Copy link
Collaborator Author

EricPoul commented Mar 2, 2023

I'll go through the changes once more and update the docs after. Once I do I'll mark this pr as ready.

@EricPoul EricPoul marked this pull request as ready for review March 3, 2023 11:45
@NetanelBasal NetanelBasal merged commit 39079a2 into ngneat:master Mar 3, 2023
@TobbiAR TobbiAR mentioned this pull request Apr 6, 2023
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants