Chris Lees
Chris Lees

Reputation: 2210

Casting results from Observable.forkJoin to their respective types in Angular 2

Let say I have a component in Angular 2 that needs to load 2 different things from the server before the page is displayed. I'd like all of those things to fire off and call one event handler when they come back telling the page isLoaded = true. Let's say I have a service class that looks like this.

export class MyService {
   getStronglyTypedData1(): Observable<StrongData1[]>{
      return this.http.get('http://...').map((response:Response) => <StrongData1[]>response.json());
   }
   getStronglyTypedData2(): Observable<StrongData2[]>{
         return this.http.get('http://...').map((response:Response) => <StrongData2[]>response.json());
   }
}

Then I have a component that uses that service class like this.

export class MyComponent implements OnInit {
   isLoaded = false;
   stronglyTypedData1: StrongData1[];
   stronglyTypedData2: StrongData2[];

   constructor(private myService:MyService){ }

   ngOnInit(){
      var requests [ 
         this.myService.getStronglyTypedData1(),
         this.myService.getStronglyTypedData2()
      ];
      Observable.forkJoin(requests).subscribe(
         results => {
            this.stronglyTypedData1 = results[0];
            this.stronglyTypedData2 = results[1];
            this.isLoaded = true;
         });
   }
}

The TypeScript compiler is complaining that it cant convert type object to type StrongData1[]. If I change StrongData1 and StrongData2 to "any", everything works fine. I'd rather not do that though because I'm losing the benefit of TypeScript's strong typings.

How do I cast the results from forkJoin to their respective types?

Upvotes: 16

Views: 20524

Answers (3)

Omar
Omar

Reputation: 1050

In Typescript you can use destructuring on function parameters (a tuple in this case):

const requests = [ 
    this.myService.getStronglyTypedData1(),
    this.myService.getStronglyTypedData2()
];
forkJoin(requests)
    .subscribe(([data1, data2]: [StrongData1[], StrongData2[]]) => {
        this.stronglyTypedData1 = data1;
        this.stronglyTypedData2 = data2;
        this.isLoaded = true;
    });

Upvotes: 11

Nicolas Gehlert
Nicolas Gehlert

Reputation: 3263

for me it always works when i add the requests directly to the Observable.forkJoin and then use es6 destructing for the result array.

so your code could look like this

Observable
    .forkJoin(this.myService.getStronglyTypedData1(), this.myService.getStronglyTypedData2())
    .subscribe(
        ([typeData1, typeData2]) => {
            this.stronglyTypedData1 = typeData1;
            this.stronglyTypedData2 = typeData2;
            this.isLoaded = true;
        }
    );

Upvotes: 22

kit
kit

Reputation: 4920

try

(results:[StrongData1[], StrongData2[]]) =>

Upvotes: 4

Related Questions