javascript - node - Filtro simple en la matriz de RXJS Observable
rxjs rx (4)
Puede hacer esto usando el flatMap
y filter
métodos de filter
de Observable
lugar del método de filtro de matriz JS en el map
. Algo como:
this.getEpics()
.flatMap((data) => data.epics) // [{id: 1}, {id: 4}, {id: 3}, ..., {id: N}]
.filter((epic) => epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe((result) => ...); // do something epic!!!
flatMap
proporcionará índices singulares para el filtrado y luego podrá continuar con lo que suceda a continuación con los resultados.
Si TypeScript arroja un error que indica que no puede comparar una cadena y un número independientemente de su uso de ==
en el filtro, simplemente agregue un +
antes de epic.id
en el filtro, según los documentos de Angular:
.flatMap(...)
.filter((epic) => +epic.id === id) // checks {id: 1}, then {id: 2}, etc
.subscribe(...)
Ejemplo:
https://stackblitz.com/edit/angular-9ehje5?file=src%2Fapp%2Fapp.component.ts
Estoy iniciando mi proyecto con Angular2 y los desarrolladores parecen recomendar RXJS Observable en lugar de Promises.
He logrado recuperar una lista de elementos (epopeyas) del servidor. Pero, ¿cómo puedo filtrar los elementos utilizando, por ejemplo, una identificación?
El siguiente código es una extracción de mi aplicación y muestra ahora la solución de trabajo final. Esperemos que ayude a alguien.
@Injectable()
export class EpicService {
private url = CONFIG.SERVER + ''/app/''; // URL to web API
constructor(private http:Http) {}
private extractData(res:Response) {
let body = res.json();
return body;
}
getEpics():Observable<Epic[]> {
return this.http.get(this.url + "getEpics")
.map(this.extractData)
.catch(this.handleError);
}
getEpic(id:string): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
}
export class EpicComponent {
errorMessage:string;
epics:Epic[];
epic:Epic;
constructor(
private requirementService:EpicService) {
}
getEpics() {
this.requirementService.getEpics()
.subscribe(
epics => this.epics = epics,
error => this.errorMessage = <any>error);
}
// actually this should be eventually in another component
getEpic(id:string) {
this.requirementService.getEpic(id)
.subscribe(
epic => this.epic = epic,
error => this.errorMessage = <any>error);
}
}
export class Epic {
id: string;
name: string;
}
Gracias de antemano por su ayuda.
Respuesta original con una solución: los Observables
son perezosos. Tiene que llamar a subscribe
para decirle a un observable
que envíe su solicitud.
getEpic(id:number) {
return this.getEpics()
.subscribe(x=>...)
.filter(epic => epic.id === id);
}
Actualización a Rxjs 6:
getEpic(id: number, callback: (epic: Epic) => void) {
this.getEpics().subscribe(
epics: Array<Epic> => {
let epic: Epic = epics.filter(epic => epic.id === id)[0];
callback(epic);
}
);
}
Usted querrá filtrar la matriz real y no el observable envuelto alrededor de ella. Así que mapearás el contenido del Observable (que es una Epic[]
) a una Epic
filtrada.
getEpic(id:number): Observable<Epic> {
return this.getEpics()
.map(epics => epics.filter(epic => epic.id === id)[0]);
}
Luego, después, puede subscribe
a getEpic
y hacer lo que quiera con él.
Observable
suscribirse a Observable
s para obtener los datos, ya que las llamadas http son asíncronas en JavaScript.
this.someService.getEpic(epicId, (epic: Epic) => {
// do something with it
});
Puedes llamar a ese método entonces así:
this.someService.getEpic(epicId, (epic: Epic) => { // do something with it });