1

I have a doubt. I can think of two approaches for child component to parent component communication.

Standard approach: For want of a better name called it the standard Approach. Its whats is commonly used. It uses @Output() EventEmitter and emitting of the event.

Alternate approach: In this event emitting is not used. Instead Parent Component's method is directly invoked from child.

It may not be as cool looking as say having (jsonStringEvent)="onJsonStringEvent($event)" inside <app-std-approach-child/>

But is simpler. I am assuming its more straightforward to debug also.

The doubt:Why do I not see anyone using the alternate approach?

Please refer here for the code if needed. https://stackblitz.com/github/doubtasker/doubt1 and https://github.com/doubtasker/doubt1.

Edit: The question is not about Subject. Its only about emiting from child to parent vs directly invoking parent method from child. When there is only 1 parent to communicate to by the child should we go for emiting or is direct invoking of parent's method good enough.

Edit: It looks to me that if the child component needs to transmit data to that one parent only he can use the method invocation. If the developer is worried about needing to use some other parent in future for his child component he can for loose coupling as needed in future write using emit.

That is not very convincing to me. But guess thats all there is to it. You can keep doing layers and layers of loose coupling but the end goal in not the loose coupling.

The most compelling if not convincing point the way I see it is what cybering said. the official document mentions only this- https://angular.io/guide/inputs-outputs#sharing-data-between-child-and-parent-directives-and-components @Output and Emitter. Its because of the official documentation we do it that way.

The big question to ask is why did the official document not say that you could also do it in a simpler way.

But cybering did say direct method invocation is also a possible approach and is available in the framework.

Finally I liked this comment of cybering the most: Your approach is valid but is restricted to the scenario where it doesn't make sense for the child component to exist without a parent. (In other words where you dont see the child being reused in another parent component)

Thanks for helping guys.

  • The questions is this- sending data from child to parent- is emitting to parent the only way? Why not just invoke a method of the parent. Please see the linked code. – user19902120 Sep 02 '22 at 08:56
  • whats difficul about invoking a method? just get a reference to the parent instance and invoke it. i would even say the emit approach which may look cooler has more steps to carry out. Is harder to debug. So why? – user19902120 Sep 02 '22 at 09:05
  • loosely coupled is good. even the other approach is loosely coupled by injection.. And when i dont need to use in 15 places( 15 places sounds more like subject - different topic) and just only 1 place should i say is safe to use the second approach – user19902120 Sep 02 '22 at 09:34
  • So if the constructor is small and its doable without any complexity that you seem to be worried about are you saying is fine to use direct method invocation? – user19902120 Sep 02 '22 at 09:39
  • 1
    Direct method invocations are. easier to read and follow any day than the context switch a emit involves. there is such a thing as being a bookish school boy programmer who does not try anything else than what is taught to him/her. use your imagination and see whats better based on real situation. All I am looking for is whether there is any really compelling reason to avoid the method invocation approach all the time. – user19902120 Sep 02 '22 at 09:48

2 Answers2

2

You actually could use component injection as a way to communicate betweeen those components but you have to be careful. In the first place in your particular case this approach could lead to a circular reference, since you are importing the child component into the parent, and the parent into the child. You could see a similar problem here.

In the other hand this kind of approach creates a strong coupling between parent and child, and in a large project with a complex logic this could lead to a hard code to mantain.

The simplest scenarios could be:

  • If you change a method name for some reason on the parent component, you should do the same in the child. This could be a nightmare if you have to perform a complete refactoring of the parent and you are using several methods from it.
  • If you want to reuse only your child component in another part of your app, that would be impossible without a proper refactoring because there is no isolation between parent and child components.

For this reasons I think that the @Output() approach is the more popular way to go and is the provided way to share data between parent and child in the official documentation.

I hope that this could provide a clear answer to your question.

EDIT:

Your approach is valid but is restricted to the scenario where it doesn't make sense for the child component to exist without a parent.

One of the main reasons we write components is to reuse them in our code, and their reusability is impossible without proper isolation. This leads you to use other approachs like the @Output.

cybering
  • 778
  • 7
  • 19
  • Circular reference can be avoided. I know that @Output is more popular. Is it more popular because people are just following what they read. It is a cool approach. But is it needed in most cases when in most cases the direct method invocation can get the job done? And arguably method invocations are easier toi debug than emit – user19902120 Sep 02 '22 at 09:36
  • Read the answer carfuly. The major pitfall for this approach is the strong coupling between parent and child – cybering Sep 02 '22 at 09:41
  • I did read it. Just did no reply to i. Now replying. Strong coupling is not always a bad thing. If in your project that child never ever needed to have a different parent why need the loose coupling? also when requirements change you will probably anyways rewrite code. In all likelihood code changes will be more than what the loose coupling will take care of – user19902120 Sep 02 '22 at 09:43
  • 1
    As I said before, you could use your approach carefuly, but your question is why the `@Output` approach is more used, and this is the answer. It ensures a more scalable and reusable code by avoiding the strong coupling that introduces your approach. – cybering Sep 02 '22 at 09:46
  • 1
    Thanks. We should possibly also keep a balance. Too much of a good thing can be bad also. We have to see what is the real need and not do just the one thing we know everywhere. We should I suppose pick the correct tools from our arsenal and use a tank where we need a tank and use a revolver where we need just that. – user19902120 Sep 02 '22 at 10:38
0

You can use the dependency injection to get a reference to the parent, with that you can access all public fields and functions.

Here is a small example: https://angular-ivy-lz6kgo.stackblitz.io

Roman P.
  • 309
  • 2
  • 10
  • Dont know why your example did no load. But Thats the approach I took in my example- https://stackblitz.com/github/doubtasker/doubt1 and https://github.com/doubtasker/doubt1. So why do I see that most angular developers insist on emitting and not doing what you just said. That was my question. Is there any reason to avoid directly invoking a method on the injected parent? – user19902120 Sep 02 '22 at 09:14
  • I don't know why the link stopped working, but it was similar to your example. I think both approaches are fine. But with the injection of the parent you have a stronger binding between the components and that limits you. With the event approach you can use you child with different parent components, because the child would not know who is consuming the event. – Roman P. Sep 02 '22 at 09:42
  • Yes I agree. But if I dont have such fancy needs I should go for simpler is best. Right? – user19902120 Sep 02 '22 at 09:49
  • 1
    There is nothing against it. I think the answer of @cybering describes it very well. It's mostly just about strong or loose coupling. – Roman P. Sep 02 '22 at 09:56
  • 2
    @user19902120 Of course you could go with your approach, that's also a feature provided by the Framework, so you could use it. It's all about the context and your needs. My answer is based in your initial question about why the other approach is more used. Is just that, is more used, not mandatory. – cybering Sep 02 '22 at 10:02
  • 1
    you cannot future proof your code. So much loose coupling? Use it when u actually need it. My point is most people are doing it wthout even needing to change that parent. Thanks. What you said made sense – user19902120 Sep 02 '22 at 10:02