Search code examples
angularviewchild

Access child component data from parent component


I have a list in the child component. I want to access this list from the parent component (AppComponent) and display it using @ViewChild decorator, but the list is always undefined in the parent component

export class CategorieComponent implements OnInit {
    @Output() listCategories: Categorie[];

    constructor(private http: HttpClient) {
        this.http.get<Categorie[]>('api/Categorie').subscribe(value => {
            this.listCategories = value;
        });
    }

    ngOnInit() {

    }
}

app-component.ts

@ViewChild(CategorieComponent, { static: false })
private categoryComponent: CategorieComponent;
.
.
.
ngAfterViewInit() {
    this.listCategories = this.categoryComponent.listCategories;
}

app.component.html

<option *ngFor="let cat of listCategories" [value]="cat.idCat" [selected]="cat.idCat == projet.idCat">
    {{cat.nomCat}}
</option>

Solution

  • Not quite sure what you're trying to do here. But since there's an AJAX call required in the CategorieComponent and you want to get informed about the data retrieval success in the AppComponent, it kinda makes sense to expose the listCategories property as an @Output property.

    But you'll then have to declare it as of type EventEmitter<Array<Categorie>>. Something like this:

    import { Component, OnInit, Output, EventEmitter } from "@angular/core";
    import { HttpClient } from "@angular/common/http";
    
    import { Categorie } from "../categorie.model";
    
    @Component({
      selector: "app-categorie",
      templateUrl: "./categorie.component.html",
      styleUrls: ["./categorie.component.css"]
    })
    export class CategorieComponent implements OnInit {
      @Output() listCategories: EventEmitter<Categorie[]> = new EventEmitter<Categorie[]>();
    
      constructor(private http: HttpClient) {}
    
      ngOnInit() {
        this.http.get<Categorie[]>("/assets/categorie.json").subscribe(value => {
          console.log(value);
          this.listCategories.emit(value);
        });
      }
    }
    

    And in the AppComponent I'm not quite sure why you're using ViewChild. You'll simply have to call a method that handles the listCategories @Output event. Something like this:

    <app-categorie 
      (listCategories)="setListCategories($event)">
    </app-categorie>
    
    <select name="" id="" *ngIf="listCategories">
      <option 
        *ngFor="let cat of listCategories" 
        [value]="cat.idCat" 
        [selected]="cat.idCat == projet.idCat">
        {{cat.nomCat}}
      </option>
    </select>
    

    You can then define the setListCategories method like this:

    listCategories: Array<Categorie>;
    projet = { };
    
    setListCategories(listCategories) {
      console.log('listCategories:: ', listCategories);
      this.listCategories = listCategories;
    }
    

    Here's a Sample Working Code for your ref.