Issue
When my component loads, I need to consume two services. Both need to be finished before it makes sense to continue. The order of completion of those is random and shouldn't be composed serially. The setup follows the pattern below.
const observables = [
this.donkeyService.getDonkey(),
this.monkeyService.getMonkey()
];
combineLatest(observables)
.subscribe(([donkeyResult, monkeyResult]) => {
if (!!donkeyResult && !!monkeyResult) {
...
}
}
We've noticed that the results aren't typed as expected. It took a while before we realized it, but the type of donkeyResult isn't Donkey, despite the definition of the server below!
getDonkey() : Observable<Donkey> { ... }
Finally, I realized that when the elements are delivered to the receiving array, they lose their typeness, since the array itself is any[]. So we manage it using casting as follows.
const observables = [
this.donkeyService.getDonkey(),
this.monkeyService.getMonkey()
];
combineLatest(observables)
.subscribe(([_1, _2]) => {
const donkeyResult = _1 as Donkey;
const monkeyResult = _2 as Monkey;
if (!!donkeyResult && !!monkeyResult) {
...
}
}
I'd like to refactor the code so that the array will retain the types specified by the service methods' signatures and won't coalesce into a common denominator any.
Is it possible to make TypeScript and/or Rxjs to have an array where the first element would be a Donkey and the second Monkey? Could I use a different data structure than an array?
I tried (and failed, of course) a bunch of different approaches including horsing around by casting the types directly in the array like so.
...
.subscribe(([_1 as Donkey, _2 as Monkey]) => { ... }
Is there a neat way to retain typeness? We're open to changing the approach altogether as we're owning this part of software and got some extra time to massage the code.
Solution
First things first, you have to type your function and your HTTP call.
getMonkey(): Observable<Donkey> {
return this.http.get<Donkey>(url);
}
Once done, you have to type your array of observables :
const observables: [Monkey, Donkey] = [
this.getMonkey(),
this.getDonkey(),
];
Finally, although not necessary, you can type your callback params :
forkJoin(observables).subscribe(([monkey, donkey]: [Monkey, Donkey]) => {...});
Answered By - user4676340
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.