Alexander Taylor
Alexander Taylor

Reputation: 17642

Providing services vs passing inputs to components

A component can require that a certain service be available and it can also accept inputs. When should it require services, and when should it require inputs?

Upvotes: 7

Views: 2534

Answers (3)

Nicollas Braga
Nicollas Braga

Reputation: 821

I would say, that you should use:

services

  • Wherever both, child and parent components must make changes to the data
  • The data lifetime should be bigger than the parent and child component.
  • The data is not important at the beginning of the component lifetime (subscribe and react on changes)
  • The data is important and required outside of the child component

Inputs and Outputs

  • The data will only be used as "read only"
  • Not shared across multiple components
  • The data must be there at the beginning of the component lifetime (onInit).
  • The data is not required/important outside of the component (can die with the child).
  • The child constructor is default [empty]

This will give better data flow visibility and decoupling of the child component.

examples:

Service:

Parent contain products > child render and edit products/ add to the cart/ order the product

Inputs and Outputs:

Parent contain products > child render/process but do not create extra data or edit the current.

Upvotes: 3

Alexander Taylor
Alexander Taylor

Reputation: 17642

Services are often good for providing one thing that is the same for a tree of components. For example, an Http service is usually the same for all components in your application. Imagine if there was no such thing as services. You'd have to duplicate the same pieces of code a lot or pass in the implementation of something everywhere its used. Every component in your application would have to pass the HttpService as input to its children.

Inputs are often good for providing one thing to one other thing. For example, passing the % complete to a progress bar is a tight interaction between the parent and child. Imagine if there was no such thing as inputs. You'd have to create a service every time you wanted to pass any information anywhere, even to simply set the value of a textbox.

Considerations:

Should the parent or user of your component be aware of the data or function that's being passed in, or is it a mere aspect of your program or part of your component tree? For example, an OrderComponent may depend on an OrderService. The parent component of OrderComponent should not necessarily know about the OrderService (it doesn't know which OrderService should be used, or which implementation of HttpService the OrderService will use etc), so it makes sense to keep it a service. For a progress bar, of course the direct parent knows the percent complete. If it doesn't know that, why is it even putting a progress bar there?

Is the data or functionality being passed directly relevant to the component's purpose? For example, the specific implementation of an HttpService is a secondary concern of any OrderComponent whose main job is to display the order (however it does that), whereas the percent complete is a primary concern of a progress bar.

Does your data change at runtime? Changing inputs trigger change detection, but a primitive value changing in a service does not. Services usually have functions, which don't change. If you have data in a service and need to use it in a component, you can put BehaviorSubjects or other Observables in the service and use the async pipe to display their values in a component template.

You may want to make a component expect a service but worry that two instances of that component in the same parent component would have to share the same provided service instance. You can avoid a parent component providing the same service to all of its children by creating another component in between that provides the service instead.

More on component interaction here: https://angular.io/docs/ts/latest/cookbook/component-communication.html

Upvotes: 5

Michael Kang
Michael Kang

Reputation: 52847

That's a good question. I think the answer comes down to whether you want a component which is coupled to a service, or whether you want a component which is more configurable and stands on its own.

There are use cases for both. For example, a component might rely on a service to get its data. The nice thing about that is that there is less to configure from the calling component (you don't have to pass in the data - it just works out-of-the-box). On the other hand, it makes the component less pluggable when you want to pass in the data instead.

Components that do not have service dependencies (i.e. to get data) may be more usable in various other contexts. For example, instead of relying on a service to get its data, the data could be passed in from the parent component through its @Input property.

Upvotes: 1

Related Questions