Search code examples
arraysangularapiunique

Trying to get a unique list of objects from an array in angular


Have an observable being returned from my service.ts as shown here:

import { Injectable, ErrorHandler } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders } from 
'@angular/common/http'
import { Observable } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { PokeResponse } from '../PokeResponse';

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

private url = "https://pokemon-go1.p.rapidapi.com/pokemon_stats.json";

constructor(private http:HttpClient) { }

getPokeData(): Observable<PokeResponse> {
  return this.http.get<PokeResponse>(this.url, 
  {
    headers : new HttpHeaders({
      'x-rapidapi-key': 'a6cef4cbcamsh05b29346394d4a4p1bafacjsn2a92406ac103'
    })
  })
.pipe(
  tap(data => console.log('Pokedata/Error' + JSON.stringify(data))
  ),
  catchError(this.handleError)
);
}

private handleError(err:HttpErrorResponse) {
console.log('PokemonService: ' + err.message);
return Observable.throw(err.message);
}
}

This is my response:

export interface PokeResponse{
list:results[];

results:{
    pokemon_id:number;
    pokemon_name:string;
    base_attack:number;
    base_defense:number;
    base_stamina:number;
}[];
}
export interface results{
    pokemon_id:number;
    pokemon_name:string;
    base_attack:number;
    base_defense:number;
    base_stamina:number;
}

export class Pokemon implements results{

    pokemon_id:number;
    pokemon_name:string;
    base_attack:number;
    base_defense:number;
    base_stamina:number;

constructor(_id:number, _name:string, _atk:number, _def:number, _stam:number) {

    _id = this.pokemon_id;
    _name = this.pokemon_name;
    _atk = this.base_attack;
    _def = this.base_defense;
    _stam = this.base_stamina;
}
}

And this is my component.ts:

import { Component, OnInit } from '@angular/core';
import { PokeApiService } from 'src/app/services/poke-api.service';
import { PokeResponse, results, Pokemon } from 'src/app/PokeResponse';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-list-pokemon',
  templateUrl: './list-pokemon.component.html',
  styleUrls: ['./list-pokemon.component.css']
})
export class ListPokemonComponent implements OnInit {

  constructor(private pokeService: PokeApiService) { }

  ngOnInit(): void {
    this.getPokeDetails();
  }

  pokeData:PokeResponse;
  errorMessage:any;

 pokeArray:results;

  getPokeDetails() : boolean {
    this.pokeService.getPokeData().subscribe(
      pokeData => {
        this.pokeData=pokeData;
        console.table(pokeData);
      },
       error => this.errorMessage = <any>error
    );
    return false;
  }
}

In my console I'm getting back a console.table of my observable like this

I'm trying to filter out the names of Pokemon which are the same as others, which could also be achieved by just filtering out any of the pokemon_ids as all the stats match regardless of the type.

So far I've tried:

console.log(this.pokeArray);,

using [...Set()], forEach(), and Array.from()

Any help or suggestions on how I can make this question any clearer would be greatly appreciated.


Solution

  • Try this, using filter:

    // list-pokemon.component.ts
    export class ListPokemonComponent implements OnInit {
      uniqueListPoke = [];
      flags = {};
    
      constructor(private pokeService: PokeApiService) { }
    
      ngOnInit(): void {
        this.getPokeDetails();
      }
    
      pokeData:PokeResponse;
      errorMessage:any;
    
     pokeArray:results;
    
      getPokeDetails() : boolean {
        this.pokeService.getPokeData().subscribe(
          pokeData => {
            this.uniqueListPoke = pokeData.filter((entry) => {
                if (this.flags[entry.pokemon_name]) {
                  // console.log('flags', false);
                    return false;
                }
                this.flags[entry.pokemon_name] = true;
                return true;
            });
            console.log(JSON.stringify(this.uniqueListPoke));
          },
           error => this.errorMessage = <any>error
        );
        return false;
      }
    }
    

    The working example: https://stackblitz.com/edit/angular-distinct-poke?file=src/app/hello.component.ts