Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Providing services vs passing inputs to components

Tags:

angular

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?

like image 273
Alexander Taylor Avatar asked Mar 02 '17 03:03

Alexander Taylor


People also ask

How to pass data through components Angular?

There are two ways to pass data into a component, with 'property binding' and 'event binding'. In Angular, data and event change detection happens top-down from parent to children. However for Angular events we can use the DOM event mental model where events flow bottom-up from child to parent.


Video Answer


2 Answers

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

like image 149
Alexander Taylor Avatar answered Nov 14 '22 04:11

Alexander Taylor


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.

like image 33
Nicollas Braga Avatar answered Nov 14 '22 05:11

Nicollas Braga