[angular] How to emit an event from parent to child?

I am currently using Angular 2. Usually we use @Output() addTab = new EventEmitter<any>(); and then addTab.emit() to emit an event to parent component.

Is there any way we can do it vice cersa, from parent to child?

This question is related to angular typescript

The answer is


In a parent component you can use @ViewChild() to access child component's method/variable.

@Component({
  selector: 'app-number-parent',
  templateUrl: './number-parent.component.html'
})
export class NumberParentComponent {
    @ViewChild(NumberComponent)
    private numberComponent: NumberComponent;
    increase() {
       this.numberComponent.increaseByOne();
    }
    decrease() {
       this.numberComponent.decreaseByOne();
    }
} 

Update:

Angular 8 onwards -

@ViewChild(NumberComponent, { static: false })

Within the parent, you can reference the child using @ViewChild. When needed (i.e. when the event would be fired), you can just execute a method in the child from the parent using the @ViewChild reference.


Using RxJs, you can declare a Subject in your parent component and pass it as Observable to child component, child component just need to subscribe to this Observable.

Parent-Component

eventsSubject: Subject<void> = new Subject<void>();

emitEventToChild() {
  this.eventsSubject.next();
}

Parent-HTML

<child [events]="eventsSubject.asObservable()"> </child>    

Child-Component

private eventsSubscription: Subscription;

@Input() events: Observable<void>;

ngOnInit(){
  this.eventsSubscription = this.events.subscribe(() => doSomething());
}

ngOnDestroy() {
  this.eventsSubscription.unsubscribe();
}

As far as I know, there are 2 standard ways you can do that.

1. @Input

Whenever the data in the parent changes, the child gets notified about this in the ngOnChanges method. The child can act on it. This is the standard way of interacting with a child.

Parent-Component
public inputToChild: Object;

Parent-HTML
<child [data]="inputToChild"> </child>       

Child-Component: @Input() data;

ngOnChanges(changes: { [property: string]: SimpleChange }){
   // Extract changes to the input property by its name
   let change: SimpleChange = changes['data']; 
// Whenever the data in the parent changes, this method gets triggered. You 
// can act on the changes here. You will have both the previous value and the 
// current value here.
}
  1. Shared service concept

Creating a service and using an observable in the shared service. The child subscribes to it and whenever there is a change, the child will be notified. This is also a popular method. When you want to send something other than the data you pass as the input, this can be used.

SharedService
subject: Subject<Object>;

Parent-Component
constructor(sharedService: SharedService)
this.sharedService.subject.next(data);

Child-Component
constructor(sharedService: SharedService)
this.sharedService.subject.subscribe((data)=>{

// Whenever the parent emits using the next method, you can receive the data 
in here and act on it.})

Use the @Input() decorator in your child component to allow the parent to bind to this input.

In the child component you declare it as is :

@Input() myInputName: myType

To bind a property from parent to a child you must add in you template the binding brackets and the name of your input between them.

Example :

<my-child-component [myChildInputName]="myParentVar"></my-child-component>

But beware, objects are passed as a reference, so if the object is updated in the child the parent's var will be too updated. This might lead to some unwanted behaviour sometime. With primary types the value is copied.

To go further read this :

Docs : https://angular.io/docs/ts/latest/cookbook/component-communication.html


Examples related to angular

error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class error TS1086: An accessor cannot be declared in an ambient context in Angular 9 TS1086: An accessor cannot be declared in ambient context @angular/material/index.d.ts' is not a module Why powershell does not run Angular commands? error: This is probably not a problem with npm. There is likely additional logging output above Angular @ViewChild() error: Expected 2 arguments, but got 1 Schema validation failed with the following errors: Data path ".builders['app-shell']" should have required property 'class' Access blocked by CORS policy: Response to preflight request doesn't pass access control check origin 'http://localhost:4200' has been blocked by CORS policy in Angular7

Examples related to typescript

TS1086: An accessor cannot be declared in ambient context Element implicitly has an 'any' type because expression of type 'string' can't be used to index Angular @ViewChild() error: Expected 2 arguments, but got 1 Typescript: No index signature with a parameter of type 'string' was found on type '{ "A": string; } Understanding esModuleInterop in tsconfig file How can I solve the error 'TS2532: Object is possibly 'undefined'? Typescript: Type 'string | undefined' is not assignable to type 'string' Typescript: Type X is missing the following properties from type Y length, pop, push, concat, and 26 more. [2740] Can't perform a React state update on an unmounted component TypeScript and React - children type?