Home > Software engineering >  How to render data in Angular from api
How to render data in Angular from api

Time:01-19

I am trying to render data from an api in the 'home.component.html', but I get an error in the browser console. The 'home.component.ts' is fetching the data correctly from my service, but I can´t manage to render it in 'home.component.html'. I may be calling it the wrong way.

The error I get is: Error: Error trying to diff '[object Object]'. Only arrays and iterables are allowed.

This is my 'home.component.html':

<div >
    <mat-card  *ngFor="let data of datas; index as i">

        <mat-card-header>
            <div mat-card-avatar ></div>
            <mat-card-title>{{ data.attributes.name }}</mat-card-title>
            <mat-card-subtitle>{{ data.attributes.publishedAt | date:'medium' }}</mat-card-subtitle>
        </mat-card-header>
        
        <img mat-card-image [src]="data.attributes.image.data.attributes.url" alt="meme">

    </mat-card>
</div>

And this is my 'home.component.ts':


import { Component, OnInit } from '@angular/core';
import { DataService } from 'src/app/services/data.service';

// import { Meme } from 'src/app/util/interfaces';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {


  datas:any=[];
  errores:string="";
  totalLength:any;

  constructor(private data: DataService) { 
  }

  ngOnInit(): void {

    this.data.getMemes().subscribe(res=>{

     const myJSON = JSON.stringify(res); 
  
     this.datas = myJSON;

     this.totalLength = res.length;

    }, error =>{
      console.log(error);
        if(error.status == 0){
            this.errores="Código del error: " error.status " \n Ha ocurrido un error del lado del cliente o un error de red.";
        }else{
            this.errores="Código del error: " error.status "\n\n" error.statusText;
        }
    })  

  }

}


This is the Browser console Error:

enter image description here

This is the JSON data from the api response, As you can see there is an array called 'data' with three objects inside:


{
  "data": [
    {
      "id": 1,
      "attributes": {
        "name": "black",
        "createdAt": "2023-01-17T19:18:29.362Z",
        "updatedAt": "2023-01-17T19:50:47.247Z",
        "publishedAt": "2023-01-17T19:37:56.037Z"
      }
    },
    {
      "id": 2,
      "attributes": {
        "name": "jennie",
        "createdAt": "2023-01-17T19:49:28.235Z",
        "updatedAt": "2023-01-17T19:51:07.573Z",
        "publishedAt": "2023-01-17T19:49:33.399Z"
      }
    },
    {
      "id": 3,
      "attributes": {
        "name": "pink",
        "createdAt": "2023-01-17T19:50:31.818Z",
        "updatedAt": "2023-01-17T19:50:56.444Z",
        "publishedAt": "2023-01-17T19:50:32.786Z"
      }
    }
  ],
  "meta": {
    "pagination": {
      "page": 1,
      "pageSize": 25,
      "pageCount": 1,
      "total": 3
    }
  }
}

And this is my 'data.service.ts':


import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { environment } from 'src/environments/environment.prod';



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

  REST_API: string ='http://localhost:1337/api/memes';

  httpHeaders = new HttpHeaders().set('Content-Type', 'application/json');

  constructor(
    private http: HttpClient
  ) {  }

  getMemes():Observable<any> {

    let API=this.REST_API;
    return this.http.get(API,{headers:this.httpHeaders}).pipe(
      map((data:any) => { 
        return data;
      }), catchError( error => {
        return throwError(error);
      })
    );

  }



}


CodePudding user response:

why are you trying to pass stringified json to an array object:

const myJSON = JSON.stringify(res);
this.datas = myJSON;

you don't need to stringify "res" object, pass res.data directly :

this.datas = res.data;

and note that your res object doesn't have "length" property :

this.totalLength = res.length

you can do this:

this.totalLength = res.meta.pagination.total:

and there is an invalid property call in your html view,there isn't image property in data.attributes:

<img mat-card-image [src]="data.attributes.image.data.attributes.url" alt="meme">

CodePudding user response:

Error : Only arrays and iterables are allowed.

Solution : Use data.json() instead of data because data it's not an array.

I think, this error is caused by this part of the code:

getMemes():Observable<any> {
  let API=this.REST_API;
  return 
  this.http.get(API, {headers:this.httpHeaders}).pipe(
      map((data:any) => {
        return data.json();
      }), catchError( error => {
        return throwError(error);
      })
    );

  }

  • Related