Search code examples
angularcomponentsprimeng

How to manipulate data coming from child component in parent component (Angular)?


I have two components -'employee-list' and 'employee-edit'

  • employee-list : a parent component
  • employee-edit : a child component

<employee-list.component.html>

<button pButton type="button" (onClick)="openDialog()">
  <i class="pi pi-pencil" aria-label="Edit"></i>
</button>
<app-employee-edit></app-employee-edit>

<employee-list.component.ts>

import { EmployeeEditComponent } from '../employee-edit/employee-edit.component';

export class EmployeeListComponent implements OnInit {
  displayDialog: boolean = false;

  @Input()
  public employeeEdit!: EmployeeEditComponent;

  openDialog() {
    this.employeeEdit.displayDialog = true;
  }
}

<employee-edit.component.html>

<p-dialog
  header="{{ employeeName }}"
  [(visible)]="displayDialog"
  [style]="{ width: '50vw' }"
  [baseZIndex]="10000"
  ><p>Employee Edit</p></p-dialog
>

<employee-edit.component.ts>

@Component({
  selector: 'app-employee-edit',
  templateUrl: './employee-edit.component.html',
  styleUrls: ['./employee-edit.component.scss'],
})
export class EmployeeEditComponent {
  displayDialog: boolean = false;
}

I want to manipulate displayDialog, which is boolean, so that the employee-edit dialog opens in another component on click by using @Input(). However, it does not work as expected.

How can I manipulate the variable coming from the child component in the parent component? Can anyone please help me out?


Solution

  • Option 1

    You want to access a child component from a parent component but you try to use @Input() for this case, what is the wrong way. @Input() is used to pass data from a parent component to a child component.
    If you want to use your child component in the code of the Parent Component you have to use @ViewChild() wich is used to get the access to manipulate the child component from the parent component:

    <employee-list.component.html>

    <button pButton type="button" (onClick)="openDialog()">
      <i class="pi pi-pencil" aria-label="Edit"></i>
    </button>
    <app-employee-edit #editComponent></app-employee-edit>
    

    <employee-list.component.ts>

    import { EmployeeEditComponent } from '../employee-edit/employee-edit.component';
    
    export class EmployeeListComponent implements OnInit {
      @ViewChild('editComponent') public employeeEdit!: EmployeeEditComponent;
    
      openDialog() {
        this.employeeEdit.displayDialog = true;
      }
    }
    

    Option 2

    Another option would be to made the displayDialog property in the child component to an Input and provide the property to the html tag:

    <employee-list.component.html>

    <button pButton type="button" (onClick)="openDialog()">
      <i class="pi pi-pencil" aria-label="Edit"></i>
    </button>
    <app-employee-edit [displayDialog]="displayDialog"></app-employee-edit>
    

    <employee-list.component.ts>

    export class EmployeeListComponent implements OnInit {
      displayDialog: boolean = false;
    
      openDialog() {
        this.displayDialog = true;
      }
    }
    

    <employee-edit.component.ts>

    @Component({
      selector: 'app-employee-edit',
      templateUrl: './employee-edit.component.html',
      styleUrls: ['./employee-edit.component.scss'],
    })
    export class EmployeeEditComponent {
      @Input() public displayDialog: boolean = false;
    }