K.Shikha
K.Shikha

Reputation: 107

How to pass asynchronous data to the child component using Angular 9

I'm making a server call using HttpClient module and getting back the response in the form of an Observable. Following is the code to get data asynchronously

let dataArr = [];
let dataObject = {};
let datafinalObject = {};

this.http.get('http://localhost:8080/api/rooms').subscribe(data => {
    if(data.length > 0) {
        dataArr.push(data);
    }

    for(const obj of data) {
        dataObject = data;
    }

    datafinalObject = dataObject;
});

And in my HTML file, I'm passing datafinalObject to the child component. Something like this

<child-component [datafinalObject]="datafinalObject"></child-component>

child-component.ts file

export class ChildComponent {
    ngOnChanges(changes: SimpleChanges) {
        if(changes.datafinalObject && changes.datafinalObject.currentValue) {
            // do some operations
        }
    }
}

Using subscribe() method, I'm getting data from the server asynchronously. Only the first result object is passed onto the datafinalObject and not the entire result set. How do I make sure that the entire result set is passed on to the child component via datafinalObject?

Upvotes: 0

Views: 1986

Answers (2)

Levidps
Levidps

Reputation: 497

Check out the design pattern behaviorsubject async pipe, it's a solid way to pass any data to a child component that can be updated at any point. This allows http calls/services to manage the data and any number of components to to update as needed to simply display the data.

In the code below you can see that I've used the async pipe in the template on *ngIf and and assigned it to a variable then passes it to the input of the child component. This provides a nice clean syntax to not display the child if the value is null and only display/pass the final object in once it has a value.

let dataArr = [];
let dataObject = {};
let datafinalObject = {};
public datafinalObject = new BehaviorSubject(null);
this.http.get('http://localhost:8080/api/rooms').subscribe(data => {
    if(data.length > 0) {
        dataArr.push(data);
    }
    for(const obj of data) {
        dataObject = data;
    }
    this.datafinalObject.next(dataObject);
});

and then in your component use

<child-component *ngIf="datafinalObject | async as finalObject" [datafinalObject]="finalObject"></child-component>

Upvotes: 2

Maddy
Maddy

Reputation: 2060

One way of doing is waiting for all the items to load (using a boolean flag), once all the items have loaded, you can pass that data to the child component.

You can directly use the dataFinalObject (unless you have to change the data first). I would recommend using an interface (for rooms)

I am creating an observable locally but you can replace that with you api call

stackblitz

  datafinalObject = {};
  itemsLoaded = false;

  constructor(private http: HttpClient) {}

  ngOnInit(){
    this.getRooms();
  }

  getRooms() {
    this.dataIs.subscribe(data => {
      if (data) {
        this.datafinalObject = data;
        this.itemsLoaded = true;
      }
    });
  }

Child Component can look like the following

<hello *ngIf=itemsLoaded [datafinalObject]="datafinalObject"></hello>

Upvotes: 0

Related Questions