Search code examples
angularangular-directiveproperty-binding

How do I extract the return value from a method in the parent component to the child component? (Angular)


I want to use the return value of a method declared in the parent component and assign it to a property in the child component.

Code for parentcomponent.ts

import { Component,Input } from '@angular/core';
import { AddlistService } from '../addlist.service';
import { TodoComponent } from '../todo/todo.component';


@Component({
  selector: 'app-all',
  templateUrl: './all.component.html',
  styleUrls: ['./all.component.css']
})
export class AllComponent {
  @Input() todo:TodoComponent={} as TodoComponent

  // constructor(private listserv:AddlistService){}
   addList(val:string){
  //  this.listserv.addTolist(this.todo)
   return val;
   }
  //  getList(){
  //   return this.listserv.get()
  //  }


 }


Code for parentcomponent.html <p> <app-todo (addList)="addList($event)"> </app-todo></p>

Code for childcomponent.ts

import { Component,Output,EventEmitter} from '@angular/core';


@Component({
  selector: 'app-todo',
  templateUrl: './todo.component.html',
  styleUrls: ['./todo.component.css']
})
export class TodoComponent {
  @Output()
  addList: EventEmitter<any> = new EventEmitter<any>()
  task:string=' ';
  constructor(){}
  assignTask(){
    
  }

In my assignTask() function in childcomponent.ts, I want to assign the empty string task to the return value val of addList() in parentcomponent.ts. I am unable to figure out a way to do so.


Solution

  • One way is to set a property on the child via a ViewChild reference:

    // parent
    import { ViewChild } from '@angular/core';
    
    import { ChildComponent } from 'wherever';
    
    @Component({
      selector: 'app-parent',
      template: `
        <app-child></app-child>
      `
    })
    export ParentComponent {
      
      @ViewChild(ChildComponent)
      childComponent: ChildComponent;
    
      addList(val: string): void {
       this.childComponent.val = val;
      }
    
    }
    
    // child
    @Component({
      selector: 'app-child',
      template: `
        {{ val }}
      `
    })
    export ParentComponent {
      
      val: string;
    
    }
    

    Another way is to use @Input() on the child to accept a value from the parent...

    // parent
    @Component({
      selector: 'app-parent',
      template: `
        <app-child [val]="val"></app-child>
      `
    })
    export ParentComponent {
      
      val: string;
    
      addList(val: string): void {
       this.val = val;
      }
    
    }
    
    // child
    @Component({
      selector: 'app-child',
      template: `
        {{ val }}
      `
    })
    export ParentComponent {
      
      @Input()
      val: string;
    
    }
    

    Something to keep in mind with @Input is that Angular's change detection only responds when the reference changes, not values. So if you're passing an array or an object, you have to pass a new reference.

    Angular documentation on parent/child communication: https://angular.io/guide/inputs-outputs