1

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 ?

2
  • Are you using HttpClient Module? Commented Jun 4, 2018 at 7:28
  • Yes I do........ Commented Jun 4, 2018 at 7:31

3 Answers 3

1

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"]);
  }
Sign up to request clarification or add additional context in comments.

Comments

0

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

Comments

0

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;
   })
);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.