Att hämta en ordlista med objekt från en ordlista med URL:er med rxjs/typescript
Jag har ett objekt såsom
let UrlObject = {
'url1' : './someurl1.json',
'url2' : './someurl2.json',..
};
Jag skulle vilja hämta alla URL:er med rxjs och låta prenumeranten veta först efter att allt har hämtats. Dessutom skulle jag också vilja att prenumeranten får ett resultatobjekt med de ursprungliga nycklarna, dvs.
let result = {
'url1' : fetchedObject1,
'url2' : fetchedObject2,..
}
Det bästa jag fick är:
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
import 'rxjs/add/operator/concatAll';
import 'rxjs/add/observable/of';
let observableBatch = [];
for (let k in urlObject) {
observableBatch.push(
this.http.get(templats[k]).map(
(res) => {
return Observable.of({[k] : res.json()})
}
)
)
}
let mergedObs =Observable.forkJoin(observableBatch).concatAll();
mergedObs.subscribe((res) => {
console.log(res);
});
Men jag får ett felmeddelande: "Egenskapen 'subscribe' finns inte på typen '{}[]'."
Hur kan jag åtgärda detta fel? Finns det ett kortare, mer elegant sätt att uppnå det jag behöver?
Svar #1
När du använder forkJoin behöver du inte använda concatAll. forkJoin prenumererar på alla käll-Observables och väntar tills alla har slutförts. Med andra ord, forkJoin sänder bara värden, inte Observables.
Hur som helst, om du inte vill skapa en array av Observable i förväg eller om källan till URL:erna inte är fast kan du till exempel göra så här:
let UrlObject = {
'url1' : './someurl1.json',
'url2' : './someurl2.json',
'url3' : './someurl3.json',
'url4' : './someurl4.json',
'url5' : './someurl5.json',
};
function httpRequest(key, url) {
return Observable.of(url)
.delay(1000)
.map(response => [key, response.split('').reverse().join('')]);
}
Observable.from(Object.keys(UrlObject).map(key => [key, UrlObject[key]]))
.flatMap(arr => httpRequest(arr[0], arr[1]))
.toArray()
.map(arr => {
const obj = {};
arr.forEach(respArr => obj[respArr[0]] = respArr[1]);
return obj;
})
.subscribe(console.log);
Detta skrivs ut till konsolen:
{ url1: 'nosj.1lruemos/.',
url2: 'nosj.2lruemos/.',
url3: 'nosj.3lruemos/.',
url4: 'nosj.4lruemos/.',
url5: 'nosj.5lruemos/.' }
Se live-demo: https://jsbin.com/hozumix/2/edit?js,console
