En la documentación de ForkJoin de Observables, dice que los argumentos pueden ser una matriz, pero no enumera un ejemplo al hacerlo:
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/forkjoin.md
Probé una función similar a la que enumeré (a continuación) pero se me ocurrió un error:
:3000/angular2/src/platform/browser/browser_adapter.js:76 EXCEPTION: TypeError: Observable_1.Observable.forkJoin is not a function
Una versión cortada de mi función a continuación:
processStuff( inputObject ) { let _self = this; return new Observable(function(observer) { let observableBatch = []; inputObject.forEach(function(componentarray, key) { observableBatch.push(_self.http.get(key + '.json').map((res: Response) => res.json())); }); Observable.forkJoin( observableBatch // ); ).subscribe(() => { observer.next(); observer.complete(); }); }); }
La raíz de mi pregunta está relacionada con un bucle para finalizar antes de continuar como se pregunta aquí: Angular2 Observable: ¿cómo esperar a que finalicen todas las llamadas de función en un bucle antes de continuar?
Pero no he dominado por completo el uso correcto de forkJoin con una matriz y la sintaxis correcta para hacerlo.
Estoy muy agradecido por la ayuda que usted podría ofrecer.
thirdFunction() { let _self = this; return Observable.create((observer) => { // return new Observable(function(observer) { ... observer.next(responseargs); observer.complete(); }); } processStuff(inputObject) { let _self = this; let observableBatch = []; inputObject.forEach((componentarray, key) => { observableBatch.push(_self.thirdFunction().map((res: Response) => res.json())); }); return Observable.forkJoin(observableBatch); } elsewhere() { this.processStuff(inputObject) .subscribe() }
Debe importar operadores que no estén cargados de forma predeterminada. Eso es lo que EXCEPTION Observable.xxxx is not a function
generalmente significa. Puede importar todos los operadores agregando rxjs
completos a su programa de arranque, por ejemplo:
import 'rxjs/Rx'
o importando operadores específicos, en su caso:
import 'rxjs/add/observable/forkJoin'
Otra observación/sugerencia sobre su código: intente ceñirse a una sintaxis. Estás mezclando es5, es6, mecanografiado... y mientras funciona, a la larga solo te confundirá. Además, si recién está comenzando con Observables, intente evitar new Observable()
y use operadores de creación en su lugar;
processStuff( inputObject ) { let observableBatch = []; inputObject.forEach(( componentarray, key ) => { observableBatch.push( this.http.get( key + '.json').map((res: Response) => res.json()) ); }); return Observable.forkJoin(observableBatch); } elsewhere() { this.processStuff( inputObject ) .subscribe() }
Finalmente, consulte la documentación correcta: Angular2 usa RxJS v5 y el enlace que proporcionó es para RxJS v4. Los documentos aún están incompletos para v5, pero puede encontrar descripciones en muchos de los archivos de origen.
Aquí hay una demostración funcional usando Angular 12. La sintaxis es un poco diferente a la respuesta aceptada (No más Observable):
https://stackblitz.com/edit/angular-map-to-forkjoin?file=src/app/app.component.ts
NOTA: Abra la consola de Herramientas para desarrolladores para ver el resultado de lo que estoy haciendo.
En primer lugar, toma una matriz de elementos JSON (en este caso, una matriz de usuarios) y los convierte en llamadas de parches HTTP individuales mediante el método de map
.
private mapCalls(users: any[]): Observable<any>[] { return users.map(user => { // Each User will be patched to the endpoint // None of these calls will be made until forkJoin is used return this.http.patch( `https://jsonplaceholder.typicode.com/users/${user.id}`, user ); }); }
Eso es ahora una matriz de Observables. forkJoin
se agrega como un contenedor para que se realicen esas llamadas
return forkJoin(mappedCalls);
Luego, se puede suscribir el resultado final, que se generará como una matriz única con el mismo número de elementos.
NOTA: Si una llamada falla en un forkJoin, TODAS FALLARAN.