I have an Angular2 app that has a service that fetches a list of items. There is a method to also fetch more specific information for each item in the list. My current setup is:
// service for item list
class ItemsService {
fetchItems(): Observable<Item[]> {
return this.http.get(url).map((res: Response) => res.json());
}
fetchItemsWithData(): Observable<Item[]> {
return this.fetchItems()
.flatMap((items: Observable<Item[]>) => items)
.map((item: Item) => this.itemService.fetchData(item))
.flatMap((items: Observable<Item[]>) => items)
.toArray();
}
}
// service for individual items
class ItemService {
fetchData(item: Item) {
return this.http.get(`${url}/${item.id}`)
.map((res: Response) => res.json());
}
}
This actually works exactly as I need it to even though the array <=> observable seems a little funky, but it does end up giving me an observable of an array of items with all of the item information.
The problem is, on the return this.fetchItems()
line I always get:
The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'Item[]' is not a valid type argument because it is not a supertype of candidate 'Observable<Item[]>'. Property 'length' is missing in type 'Observable<Item[]>'.
I'm at a bit of a loss since fetchItems
does return an Observable
and changing it to Observable<any>
gives the same error. If I just change it to any
though I don't get any error reports at all.
Is there a better type to use for fetchItems
?
When I ran into same issue, the reason was that I forgot to import Response
class:
import { Http, Response } from '@angular/http';
Hope it helps someone.
I'm suspicious this might have something to do with toArray()
which returns Observable<T[]>
.
In your case where you define fetchItems(): Observable<Item[]>
it makes toArray()
to return Observable<Observable<Item[]>[]>
so that's why it throws an error even with Observable<any>
.
Btw I tried to simulate your situation with just mock classes and it compiled without errors (TypeScript 2.0.3) but maybe I made an error somewhere and its not identical (?):
class Observable<T> {
map(_): Observable<T> { return new Observable<T>() }
flatMap(_): Observable<T> { return new Observable<T>() }
toArray(): Observable<T[]> { return new Observable<T[]>() }
}
class Item { }
class Response {
json() { }
}
class HTTP {
get(_) { return new Observable() }
}
class ItemsService {
itemService = new ItemService();
http = new HTTP();
fetchItems(): Observable<Item[]> {
return this.http.get('url').map((res: Response) => res.json());
}
fetchItemsWithData(): Observable<Item[]> {
return this.fetchItems()
.flatMap((items: Observable<Item[]>) => items)
.map((item: Item) => this.itemService.fetchData(item))
.flatMap((items: Observable<Item[]>) => items)
.toArray();
}
}
// service for individual items
class ItemService {
http = new HTTP();
fetchData(item: Item) {
return this.http.get('url')
.map((res: Response) => res.json());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With