#Passing Data Between Components.
There are different ways to pass data in and out of components. It can be a simple property or method being passed from parent to children. Or, it could be any complex object from one parent component to a deeply nested child component. They approach differs on the complexity of the application and the relationship between the components.
#Passing Data from Parent to Child
#Using @Input decorator
When the data is passed from a parent to child component, we use @Input()
decorator. In the parent component, we specify the variable name which holds the data that is being passed and bind it to the child components view inside []
brackets.
In the child component, we declare the same variable name by decorating it with @Input()
so that Angular will know the value will be sent from a parent component.
This is a one-way relationship: parent to child. Only parent can send the data to child.
#Passing Data from Child to Parent
There are different ways that a child component can pass data to the parent. The two most commonly used patterns are:
@ViewChild()
decorator in parent component@Output()
decorator andEventEmitter
class in child component
#Using @ViewChild Decorator
This decorator is used in parent component to create a reference to it's child component. By doing this, we will get access to all the public properties of the child component.
Once the child component properties are set, we can use ngAfterViewInit
lifecycle hook in parent to read the child components properties and update in the template.
#Using @Output Decorator and EventEmitter Class
This decorator is used in child component alongside with EventEmitter
class. This approach involves defining events in child components and the parent component can listen to these events.
This approach is ideal when child component needs to let the parent component know of events happening inside it like button clicks etc.
In the first approach, we can clearly see there is a tight cohesion between the parent and child component because of the reference it holds. Meanwhile, in the second approach, there is no such cohesion as the communication is happening through events. Any parent component can register itself to listen to these events. It's up to them. This leads to better separation of concerns.
#Passing Data Between Unrelated Components
In a complex application with many number of components, there will be a scenario where you set some data in one component and read that same data in another component. These components need not to have a parent/child relationship. They could be unrelated components with no common parent.
#Using Shared Service
Passing data between unrelated components can be done using a shared service. They contain all the data objects which are read and updated by any component. We will define getters and setters to read and update the shared data values.
The below service is a typescript class which has a single private property which will be shared across all the components. The important part is @Injectable
decorator. This tells Angular that this class can be injected into other components.
To use the service, we inject them into the required component's constructor. This is commonly known as Dependency Injection. It's a pattern where the objects are injected into the classes. Once the objects are injected, we can use ngOnInit()
lifecycle hook to read the service class data objects and set it to the components variables.
Angular will be using the Singleton design pattern for all the injectable services to make sure that only one instance of the class is available, and the data is reflected in all the components if it is changed in any one of the component.
In this component we are injecting the data service and updating the message on a button click. The data will be updated in the service class and also in all the other components where this data is being read.