How do I fill an Angular Boostrap Table Widget with data returned from an API call?

275 views Asked by At

I am trying to make an API call and use that data I receive to use in a Bootstrap Angular Table Widget.

The widget I am using: Complete example (Angular powered bootstrap widget)

Make sure you are working with the complete example, the one with the service and pagination etc.

I tried replacing the this.countries with the response form my api call.

constructor(public service: CountryService) {
    this.countries$ = service.countries$;
    this.total$ = service.total$;
        this.headers = new QueryList<NgbdSortableHeader>();
}

Api service:

getusers2() {
    return this.http.get<Country[]>(this.getusersEndpoint, this.httpOptions);
}

This partially works, because I get the expected output in the table, but the service still uses the hard coded class COUNTRIES. So the filtering and pagination and searching doesn't work. How can I get this to work?

The main goal is to make a skeleton table on de page, fetch the data, and when the data is fetched display the correct table with response from api.

What would be ideal is something in this way:

<ngbd-table-skeleton ngIf=loading></ngbd-table-skeleton>
<ngbd-table-complete ngIf=!loading [data]="countries"></ngbd-table-complete>

where I would set loading in OnInit to true, fetch data, set the data, set loading to false, display the correct table with working pagination, filtering and sorting.

This could be completely impossible, my Angular knowledge isn't yet on point. If this way of doing it is possible, I would love to hear from anyone with a possible solution.

1

There are 1 answers

8
Eliseo On

The key is working with the "country.service". You should change to return the value of the API, not a hardcode "COUNTRIES". futhermore you need use "pipe(map)" to work with observables

Really you should pass to the API the values of sortColumn, sortDirection, pageSize, page and searchTermsort to return only the elements necessary. In this way you should replace the function _search by some like

So the function _search becomes like

private _search(): Observable<SearchResult> {
    const { sortColumn, sortDirection, pageSize, page, searchTerm } =this._state;
      return this.httpClient.get(....) //<--call to your API

If there're a few items, you can "cache" the values and return or the cache or the call to your API that return the "whole" countries

countries:Country[]; //<--a variable to store the whole countries

private _search(): Observable<SearchResult> {
    const { sortColumn, sortDirection, pageSize, page, searchTerm } =
      this._state;
   
    //if "this.countries" have values, obs%= of(this.countries)
    //else obs$=the call to your API

    const obs$=this.countries?of(this.countries):
               this.httpClient.get(..).pipe(tap((res: Country[])=>{
                    this.countries=res;
               }))

    //we work with observables using "pipe"
    return obs$.pipe(
      map((res: Country[]) => {
        //you sort:
        let countries = sort(res, sortColumn, sortDirection);

        //filter
        countries = countries.filter((country) =>
          matches(country, searchTerm, this.pipe)
        );
        const total = countries.length;

        //paginate
        countries = countries.slice(
          (page - 1) * pageSize,
          (page - 1) * pageSize + pageSize
        );

        return { countries, total };
      })
    );
  }

See that work with observables is much close to work with an array. You "enclosed" in a pipe.map