Angular - @Input and @Output vs. Injectable Service Angular - @Input and @Output vs. Injectable Service typescript typescript

Angular - @Input and @Output vs. Injectable Service


Not exactly a question with a defined answer, but....

@Input and @Output are useful if the communication between a parent and child is just that, between a parent and child. It wouldn't make sense to have a service that maintains singleton data for just 2 components (or however deeply nested grandparent -> parent -> child components are).

They're also useful if your parent needs to react to a change in the child. For example, clicking a button in a child component that calls a function in the parent:

<my-child-component (myOutputEmitter)="reactToChildChange($event)"></my-child-component>

And in parent:

reactToChildChange(data: any) {  // do something with data}

If you find yourself passing many @Input properties to a child, and want to tidy up a template, then you can define an interface for the input, and pass it instead. e.g.

export interface MyChildProperties {   property?: any;   anotherProperty?: any;   andAnotherProperty?: any;}

Then you can pass a definition to your child, which is set from the parent:

childProperties: MyChildProperties = {    property: 'foo',    anotherProperty: 'bar',    andAnotherProperty: 'zoob'}

Then your child component may have:

@Input properties: MyChildProperties;

and your template becomes:

<my-child-component [properties]="childProperties"></my-child-component>

Your child can access those properties from properties.property, properties.anotherProperty, etc.

Clean, tidy, and your data is now contained to those components that need to communicate.

Services, however, should be used where more than one component needs access to read/write data across your entire application. Consider a UserService for example, where many different components need to be able to access the currently logged in user. In this case, a service is sensible, as its a singleton, so once you have set your logged in user, any components that inject the UserService can access its data and functions.

Similarly, if you were to use a service for reacting to change, then you'd find yourself writing services with observables so that your components could subscribe to changes in the data. Eventemitters already give you this pattern with @Output as shown above.

If it were a simple parent -> child communication, this is unnecessary overhead, and should be avoided.

That said, if you find yourself using services to manage global state, you'd be better off using some form of state management such as ngrx