Juliatzin
Juliatzin

Reputation: 19695

How to parse data object from json in angular

I am just beginning with Angular 6.

I folllowed the Hero Tutorial, and then replaced it with a real local API

now, instead of heroes, I have tournaments

but my API instead of returning an array of tournaments, it wraps it into a data object, so I can add metadata.

tournament.service.ts

getTournaments(): Observable<Tournament[]> {
    this.messageService.add('TournamentService: fetched tournaments');
    return this.http.get<Tournament[]>(this.tournamentsUrl)
      .pipe(
        tap(tournaments => this.log(`fetched tournaments`)),
        catchError(this.handleError('getTournaments', []))
      );
  }

tournament.ts

export class Tournament {
  id: number;
  user: string;
  date: string;
  name: string;
  numCompetitors: number;
}

tournaments I get from API:

"data": [
{
"id": 1,
"user": "[email protected]",
"date": "2018-06-13",
"name": "Fake Tournoi",
"numCompetitors": 86
},
{
"id": 2,
"user": "[email protected]",
"date": "2018-06-06",
"name": "Noel Kerluke",
"numCompetitors": 0
},
]

How should I do to always extract my array from data ?

Upvotes: 1

Views: 1446

Answers (3)

ashish pal
ashish pal

Reputation: 467

if tournaments is a object then, in component where you are subscribing the service method then you have to get that array of data like this tournaments["data"]

getTournaments(): void {
    this.tournamentService.getTournaments()
    .subscribe(tournaments => this.tournaments= tournaments["data"]);
  }

Upvotes: 1

Matthias Sommer
Matthias Sommer

Reputation: 1088

Usually, I write a mapper from DTO to model class following DDD principles. In your case, it would be something like

export class TournamentMapper implements DtoMapper {
    map(resp: TournamentResponse): Tournament {
        return new Tournament(resp.Id, resp.User, resp.Date, resp.Name, resp.numCompetitors);
    }
}

In your HTTP Get, I would add a map() to transform the DTO array to an array of your Tournament model.

return this.http.get<Tournament[]>(this.tournamentsUrl).pipe(
   tap(tournaments => this.log(`fetched tournaments`)),
   catchError(this.handleError('getTournaments', [])).
   map((resp: Array<TournamentResponse>) => {
       const tournaments: Array<Tournament> = [];
       resp.forEach(tournament => tournaments.push(this.tournamentMapper.map(tournament)));
       return tournaments;
   })
);

Upvotes: 0

Rohit Kavthekar
Rohit Kavthekar

Reputation: 339

You can do like this :

1 create tournament array
2 add {observe : 'response'} in get method options
3 instead of using map use subscribe method to get response body like below code

Complete Solution :

private tournament : Tournament[];

getTournaments(): Observable<Tournament[]> {

    this.messageService.add('TournamentService: fetched tournaments');

    return this.http.get<Tournament[]>(this.tournamentsUrl,{observe: 'response'})
      .subscribe(response => {this.tournament = response.body}),
        catchError(this.handleError('getTournaments', []))
      );
  }

All your tournament data is fetched into your Tournament array and you can use as you want

Upvotes: 0

Related Questions