Davide
Davide

Reputation: 185

Passing asynchronous value from parent to child component with @Input

I am trying to pass a map, which come from an api, from parent to child component, in angular 7.

parent.ts:

export class AppComponent {
  title = 'taurs-frontend';
  categories: any;
  isLoggedIn = false;

ngOnInit(){
    this.roomDataService.getData(`${environment.api_url}/api/Categories`)
    .subscribe(categories => {
      this.categories=categories
    }); 
  }

parent.html:

 <app-room-card [categories]="categories"></app-room-card> 

child.ts:

@Component({
  selector: 'app-room-card',
  templateUrl: './room-card.component.html',
  styleUrls: ['./room-card.component.css']
})
export class RoomCardComponent implements OnInit {
    @Input('categories') catname: any;

    ngOnInit() {
        console.log('aaa'+ this.catname);
    }
// ..
}

When I try to log the variable catname, it is undefined. If I try to import variable title from the parent, everything works properly. How can I pass categories to the child, filling it with the values from the API call?

Upvotes: 6

Views: 5800

Answers (3)

Carlos Morales
Carlos Morales

Reputation: 92

I had the same issue, i fixed with a variable "loading" of type boolean;

export class AppComponent {
  title = 'taurs-frontend';
  categories: any;
  isLoggedIn = false;
  loading:boolean = false; -> // my variable

ngOnInit(){
    this.loading = true; -> // true when the request starts 
    this.roomDataService.getData(`${environment.api_url}/api/Categories`)
    .subscribe(categories => {
      this.categories=categories
      this.loading = false; // false with the request ends
    }); 
  }

So, in HTML

 <app-room-card *ngIf="!loading" [categories]="categories"></app-room-card> 
 // i used this variable to wait data of my parent component 

I hope this solves your problem or helps someone else.

Upvotes: -2

veben
veben

Reputation: 22262

You are trying to pass asynchronous data to child component. You have different solutions to do that. For exemple, you can use ngOnChanges instead of ngOnInit:

ngOnChanges() {
    console.log('aaa'+ this.catname);
}

Another solution is to use *ngIf, in order to delay the initialization of posts components:

<app-room-card *ngIf="categories" [categories]="categories"></app-room-card>

Take a look at this link: https://scotch.io/tutorials/3-ways-to-pass-async-data-to-angular-2-child-components#toc-solution-2-use-ngonchanges

Upvotes: 18

Sajeetharan
Sajeetharan

Reputation: 222522

Try changing your component code as,

export class RoomCardComponent implements OnInit {
   @Input() categories: any; 
   ngOnInit() {
   console.log('aaa'+ this.categories);
   }
}

and have *ngIf on the parent component just to make sure the data is passed to child once you get the response from your API

<app-room-card *ngIf="categories" [categories]="categories"></app-room-card> 

Upvotes: 6

Related Questions