> Faqs > Filtrar los datos que te devuelve un observable, subscribe()

Filtrar los datos que te devuelve un observable, subscribe()

Al realizar una consulta para traer un JSON del servidor, me gustaría saber si es posible realizar una consulta sobre los datos JSON devueltos en la subscripción, ya que me gustaría extraer por tipos.

Este es mi código del componente Servicio:

import { Injectable } from '@angular/core';
import { Potion, POTIONTYPE } from './potion-model';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';


@Injectable({
  providedIn: 'root'
})

export class PotionService {

  constructor(private http: HttpClient) { }
  
  public obtenerPociones(): Observable<Potion[]>{
    const urlEndPoint = "http://localhost:8080/api/pociones";
    return this.http.get<Potion[]>(urlEndPoint);
  }
  
}

y este es el código del componente para la subscripción:

import { Component, OnInit } from '@angular/core';
import { Potion } from '../potion-model';
import { PotionService } from '../potion.service';

@Component({
  selector: 'app-potion-list-bd',
  templateUrl: './potion-list-bd.component.html',
  styleUrls: ['./potion-list-bd.component.css']
})
export class PotionListBDComponent implements OnInit {
  pociones: Potion[] = [];

  constructor(private pocionService: PotionService) { }
 
   ngOnInit(): void {
    this.pocionService.obtenerPociones().subscribe(pocionesAsincronas => this.pociones = pocionesAsincronas);
   }
  
 }

puedo ver el listado JSON completo en el html:

<pre>{{pociones | json}}</pre>

Este es el modelo Pocion:

export enum POTIONTYPE {
   VIDA,
   MANA,
   ENERGIA
}

export class Potion {
   id: number;
   titulo:string;
   descripcion: string;
   urlImagen: string;
   tipo: POTIONTYPE;
   esEpica: boolean;

   constructor(id:number, titulo:string, descripcion:string, urlImagen: string,
       tipo: POTIONTYPE, esEpica: boolean) {
      this.id = id;
      this.titulo = titulo;
      this.descripcion = descripcion;
      this.urlImagen = urlImagen;
      this.tipo = tipo;
      this.esEpica = esEpica;
   }
}

Respuestas

Para filtrar los datos que te devuelve un observable, con rxjs puedes hacer uso del método pipe del observable.

El el código de tu componente, cuando haces la suscripción, puedes hacer el filtrado con algo como esto:

Importo la función map que voy a necesitar

import { map } from 'rxjs/operators';

En el ngOnInit hago el filtrado.

ngOnInit(): void {
    this.usersService.getUsers().pipe(
        map(users => 
          users.filter(user => user.name.toLowerCase().indexOf('m') != -1)
        )
      ).subscribe(
        users => this.users = users
      )
}

Así estoy obteniendo los usuarios que tienen la letra "m" en el nombre. Quizás ese código de filtrado estaría mejor en el servicio, no obstante, te vale como referencia.

Filtrado usando pipes

Ahora bien, realmente en la mayoría de los casos los filtrados los querrás realizar en función de datos de tu programa, y muchas veces en tiempo real, es decir: a medida que los criterios de filtrado cambian, cambian los datos que se muestran. Para ello es mucho más lógico usar pipes.

En este artículo encuentras las explicaciones y código de ejemplo para crear con pipes en Angular que te permitan filtrados.

Miguel Angel
1686 78 107 5
Muchas gracias por la respuesta además de link al artículo Miguel Ángel, pruebo y te comento. Un saludo.

Hola, ya he podido comprobar que funciona usando el método pipe del observable. También he probado aplicando un filter por cada enumerado:

 ngOnInit(): void {
    this.pocionService.obtenerPociones().subscribe(

      result => {
        this.pociones = result; 
        this.pocionesMana = this.pociones.filter(pocion => pocion.tipo.toString() === 'MANA');
        this.pocionesEnergia = this.pociones.filter(pocion => pocion.tipo.toString() === 'ENERGIA');
        this.pocionesVida = this.pociones.filter(pocion => pocion.tipo.toString() === 'VIDA');
      }

    );
       
    //this.pocionService.obtenerPociones().subscribe(pocionesAsincronas => this.pociones = pocionesAsincronas);
  }

Muchas gracias por la ayuda...

José Luis
7 1 1
Gracias por publicar tu solución!