0
votes

I have a relationship between two components (one.component and two.component) and I have a service (global.service) between the two. Everything works well (I can pass values from one to another like that in Angular 2 - Parent and children communicate via a service from the Angular.io site). I have a global variable in global.service that is deleted from one.component, when that happens I need to trigger an even in two.component. I'm thinking that I can pass a boolean variable from global.service to two.component through an observable when this happens. But, because I don't need the variable, I'm thinking there must be a better way to just call a method in two.component from global.service.

Thank you!

2

2 Answers

1
votes

In terms of how to do that I think it would come down to trying to get a reference to your root component and then working your way through its children until you find the component you are looking for. I don't know how to do that though, or if it is even possible, because my actual answer is:

I don't think you want to do that.

Having the component subscribe to an observable from your service is very standard and easy to follow behavior, even if it only gets one variable. You can look at your component and see exactly what is triggering all of its inputs and outputs. If you make it possible for your service to reach out and programmaticaly adjust your component, I think it will be easy to lose track of that fact in the long run and have hard-to-track-down behavior. You've basically gone from having two guys in charge of your systems behavior (Component 1 and Component 2) to having three things in charge: Component 1, Component 2, and Service 1.

It's much better, IMO, to let Services be simple containers of data, and let the components themselves decide when/how/where they change in response to the changing state.

1
votes

You usually want to separate the service logic from the usage.
My suggestion is to save a Subject (or BehaviorSubject, depends on the usage of the service) in the service,
and have the parent component next it, and the child component will subscribe to that Observable(every Subject is an observable, you can use Subject.toObservable when returning it to make sure you don't give the Subject in the API).

I have a great example to give out.

I'm currently working on a project that has a canvas that receives keyboard input from window, and also, I have a chat in the same page. Before the fix I'm about to explain to you, whenever I pressed any of WASD in the chat, it would cause the canvas to receive the input (effectively moving the character).

What I wanted to do, is to intercept input whenever I'm in the chat.

I have a service, called GameInputDisableService, which is responsible for the interception. It saves a BehaviorSubject, which is initialized to false.

I have the MessageInputComponent(TS, HTML), where I inject the service in the TS, and call the service methods in the input's focus and focusout events.

On the other end, I have the AioGameComponent(TS), which has an @Input() disableInput: boolean, the component which wraps this component transfers the value saved in GameInputDisableService to the AioGameComponent

I hope this works for you, sounds like this kind of service can help you.
The difference is that you might want to subscribe to the observable and call your compnent's method, instead of transferring the value in an @Input to the child component