1

Trying to pass the array value from the parent component to the child component using httpclient get method. So, I have used an input decorator. But, In my code, I am not able to pass the array value. Because the child component is loaded before the parent component. That's why i am not able to pass the data inside the get method. How to resolve this issue?

app.component.ts:

    public allData = []; 
    constructor(private httpClient: HttpClient) {} 
    ngOnInit(): void {
    this.httpClient.get<string[]>('assets/data.json').subscribe((data) => {
      this.allData = data;
      console.log('GetData');
      console.log(data);
    });
    }

auto.component.ts:

  @Input() data: Array<string> = [];
  public rateData:any;
  
  constructor() {
   
  }

  ngOnInit(): void { 
    console.log("thisdata");
    console.log(this.data)
    this.rateData =this.data;
  }

Demo: https://stackblitz.com/edit/angular-ivy-1jw62m?file=src%2Fapp%2Fauto%2Fauto.component.ts

EMahan K
  • 417
  • 1
  • 19
  • It depends on what you want to happen while the information is not available. If it shouldn't display anything, consider a `*ngIf`, as in ``. – Edu Müller Jul 14 '22 at 16:13
  • Does this answer your question? [Angular2 - pass ASYNC data to child component](https://stackoverflow.com/questions/41692222/angular2-pass-async-data-to-child-component) – Heretic Monkey Jul 14 '22 at 16:22

3 Answers3

0

The problem is that the ngOnInit lifecycle-hook runs at a specific point in time, after the constructor. Your GET-request is async and resolves at some unknown time, probably way after your child component is created. Thus, way past you child's ngOnInit has run. Thus, ngOnInit really has nothing to work with.

You have two options of fixing this: By using the ngOnChanges hook (a bit complex, not recommended), or by using a setter for the input, which will run whenever the input value changes. The latter I would recommend.

I have forked your project to demonstrate: https://stackblitz.com/edit/angular-ivy-va1se8?file=src%2Fapp%2Fauto%2Fauto.component.ts,src%2Fapp%2Fauto%2Fauto.component.html,src%2Fapp%2Fapp.component.ts

NoBullsh1t
  • 483
  • 4
  • 14
0

You need to implement OnChanges interface and add ngOnChanges class method and manually update your field. OnInit recieves null and it does not get called later.

Docs: https://angular.io/api/core/OnChanges

app.component.ts

import { Component, VERSION, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  name = 'Angular ' + VERSION.major;

  public readonly allData$: Observable<string[]>; 

  constructor(private httpClient: HttpClient) {
    this.allData$ = this.httpClient.get<string[]>('assets/data.json');
  }

  ngOnInit(): void {}
}

app.component.html

<hello name="{{ name }}"></hello>
<p>Start editing to see some magic happen :)</p>

<app-auto [data]="allData$ | async"></app-auto>

auto.component.ts

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';

@Component({
  selector: 'app-auto',
  templateUrl: './auto.component.html',
  styleUrls: ['./auto.component.css']
})
export class AutoComponent implements OnChanges {

  @Input() data: Array<string> = [];
  public rateData: string[] = [];
  
  constructor() {
  }
  
  ngOnChanges(changes: SimpleChanges) {
    this.rateData = changes.data.currentValue;
  }
}

auto.component.html

{{ rateData | json }}
Sergey Sosunov
  • 4,124
  • 2
  • 11
  • 15
0

Yes you can add an onChanges to your child component and track the changes but if its just a matter of reacting to one single property change you can convert your @Input to setter/getter also e.g.

  private _data: string[];
  @Input() set data(val: string[]) {
    this._data = val;
    this.rateData = val;
  }
  get data(): string[] {
    return this._data;
  }

Updated: https://stackblitz.com/edit/angular-ivy-jfgmrs?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts,src%2Fapp%2Fauto%2Fauto.component.html,src%2Fapp%2Fauto%2Fauto.component.ts

However i would suggest that you change your parent component's change detection to OnPush and manually trigger change detection also. In Auto change detection, angualr is running cd unncessarily and you can trigger it only when you receive the data.

Suresh Nagar
  • 1,021
  • 9
  • 20