Why to use Subject or BehaviorSubject in services when angular can detect latest values?

Viewed 687

For example we have a service that has a list of items in it. When we change this list in the service, all of the components that are using this list will detect this change. for example if you add a new item all of the components will detect it. so why should we use subjects or BehaviorSubject when angular can detect changes itself ?

4 Answers

Change detection is a great way to update the DOM after data changes. But what if you want to do more than that? What if a component needs to react to a change by executing some code?

If the change flows downwards in the component tree, you can do this by leveraging @Input. But what if you need to communicate sideways, upwards, or independent of the shape of the tree? Being constrained to unidirectional data flow, angular change detection can't help with that, so you need a different way to propagate changes for that. And that's what Observables are for.

The pattern of creating a service with a Subject/BehaviourSubject is mostly used to pass data between components that lack a direct connection. For direct connection, I mean two components that don't have any relation such as parent/children, siblings, grandchildren.

Imagine you have two components that need to share data without that direct connection, how would you pass data between those components (since you can't use Input(), Output() + EventEmitter, ViewChild(), ViewChildren()) ? How would one component know when another component property is changed?

For this reason, we create a service with a subject/behaviour Subject (will simply call it Subject from now on). Every component that needs to be updated with the latest emission will inject this service and subscribe() to the subject. So that when we next() a value in the Subject, every component subscribed to the Subject will get the latest emission. When the Subject emits, you can run some logic (e.g assign the emission to a component property or run some component methods with that emission as an argument).

Only if the components have a direct connection, your question is legit:

Why to use Subject or BehaviorSubject in services when angular can detect latest values?

In that case, there is nothing wrong with just using @Input() and @Output() + EventEmitter to pass data between components. But you may still want to implement the pattern of service + Subject if, for example, the parent component needs to share the data with his grand-grand-grand-children. You might want to avoid passing data between two components, when one is nested really deep. You would have to follow the whole component chain with @Input() and @Output() + EventEmitter as many times as the number of nested components. In that case, you might just go with the service + Subject to have a cleaner end result.

If you want to notice the change from the typescript section(*.ts) You have to use the observables such as Subject, BehaviorSubject, etc.

You can use Subject, BehaviorSubject, EventEmitter or whatever you want to reach the target. Who makes you use exactly Subject or BehaviorSubject? If you ask about ChangeDetectionStrategy - you are confusing concepts and you should take a course in Angular, because ChangeDetectionStrategy is about inputs (@Input() something: string) in components and their changes

Related