How to combine multiple REST API JSON output and show in MatTable Angular

Viewed 81

I'm calling four different REST endpoints, I want to combine all these results into single JSON and show in the Angular Mat table. I tried pushing into an array but its creating nested JSON object and not showing anything in table. Please find my code below:

post.component.ts

import { Component, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { MatTableDataSource } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, Sort } from '@angular/material/sort';
import { LiveAnnouncer } from '@angular/cdk/a11y';
import { PostService } from './post-service';
import { Post } from './post';

export class PostComponent implements OnInit {


    @ViewChild(MatPaginator) paginator: MatPaginator;
    @ViewChild(MatSort) sort: MatSort;

    post: Post[];
    dataSource;
    columnsToDisplay = ['postId', 'id', 'name', 'email', 'body'];
    my_array = [];

    /**
     * Constructor
     */
    constructor(
        private postService: PostService,
        private _liveAnnouncer: LiveAnnouncer,
        private cdr: ChangeDetectorRef) { }

    listPost() {
        this.onGetPost('post-1');
        this.onGetPost('post-2');
        this.onGetPost('post-3');
        this.onGetPost('post-4');
    }

    onGetPost(postId): void {
        this.postService.getPost(postId).subscribe(
            (response) => {
                console.log(response);
                this.my_array.push(response);
                this.post = this.my_array;
                this.dataSource = new MatTableDataSource(this.post);
                this.cdr.detectChanges();
                this.dataSource.paginator = this.paginator;
                this.dataSource.sort = this.sort;
            },
            (error: any) => {
                console.log('entering into error block')
                console.log(error)
                this.dataSource = new MatTableDataSource();
                this.cdr.detectChanges();
                this.dataSource.paginator = this.paginator;
                this.dataSource.sort = this.sort;

            },
            () => console.log('Done getting all post')
        );
    }

    filterData($event: any) {
        this.dataSource.filter = $event.target.value;
    }
    announceSortChange(sortState: Sort) {
        if (sortState.direction) {
            this._liveAnnouncer.announce(`Sorted ${sortState.direction}ending`);
        } else {
            this._liveAnnouncer.announce('Sorting cleared');
        }
    }

    /**
     * On init
     */
    ngOnInit(): void {
        this.listPost();

    }

}

post-service.ts

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { Post } from "./post";

@Injectable({ providedIn: 'root' })
export class PostService {

    constructor(private http: HttpClient) { }
    endpoint: any;
    getPost(id): Observable<Post[]> {

        console.log(id);
        switch (id) {
            case 'post-1':
                this.endpoint = 'https://jsonplaceholder.typicode.com/posts/1/comments';
                break;
            case 'post-2':
                this.endpoint = 'https://jsonplaceholder.typicode.com/posts/2/comments';
                break;
            case 'post-3':
                this.endpoint = 'https://jsonplaceholder.typicode.com/posts/3/comments';
                break;
            case 'post-4':
                this.endpoint = 'https://jsonplaceholder.typicode.com/posts/4/comments';
                break;
        }
        return this.http.get<Post[]>(this.endpoint);
    }
}

Could you please help me to resolve this issue. Appreciated your support on this. Thanks!

1 Answers

you can use RxJs and use pipe and switchMap , then in every switch map try to concat results of API's
swithcMap refrence

another way is using forkJoin , first change result of onGetPost to observable and then you code can be like this :

let fk = [];
fk.push(onGetPost('x'));
fk.push(onGetPost('y'));
fk.push(onGetPost('z'));

after that

forkJoin(fk).subscribe(a=> { code to concat result})

concat result of the forkJoin

forkJoin refrence

with fork join you can get onGetPost with different id's dynamically

Related