Reputation: 607
When trying to subscribe to the result of a forkJoin inside the onInit function, I get the following error:
error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '((next: (value: Result[]) => void, promiseCtor?: PromiseConstructorLike) => Promise) | ((next: (value: Account[]) => void, promiseCtor?: PromiseConstructorLike) => Promise)' has no compatible call signatures.
getAccounts returns an observable of Account[], getResults returns an observable of Result[]. When both are finished loading, I'm trying to get the detailed account results from another database, using the accessToken of the accounts retrieved from the getAccounts function, so that I can add the results to the detailed accounts.
In short I'm trying to achieve this:
let var = getAccountsSimplified();
let var2 = getAllResults();
if both are finished{
foreach(acc in var) {
account = getDetailedAccount(acc.id)
var ownedResults = var2.where(userid === acc.id)
account.results = ownedResults
}
}
This is what I tried so far, but for some reason it is causing the error mentioned above.
For some reason the console.log(user)
is working fine, which is why I'm completely lost at the error.
const tasks$ = [
this.aus.getAccounts(this.auth.token),
this.rs.getResults(this.auth.token)
];
forkJoin(tasks$).subscribe(
value => {
const userList = value[0];
const resultList = value[1];
userList.forEach((acc: Account) => {
this.aus.getUserDetails(acc.access_token).subscribe((user: User) => {
if (user != null) {
console.log(user);
}
});
});
}
);
Signatures of called functions:
getAccounts(auth: string): Observable<Array<Account>> {
}
getResults(auth: string): Observable<Array<Result>> {
}
getUserDetails(token: string): Observable<User> {
}
Update
After adding Kurt's suggestion, I'm now getting
Argument of type 'MonoTypeOperatorFunction<[Account[], Result[]]>' is not assignable to parameter of type 'OperatorFunction<(Observable | Observable)[], [Account[], Result[]]>'. Types of parameters 'source' and 'source' are incompatible. Type 'Observable<(Observable | Observable)[]>' is not assignable to type 'Observable<[Account[], Result[]]>'. Type '(Observable | Observable)[]' is missing the following properties from type '[Account[], Result[]]': 0, 1ts(2345)
It seems as if there is a problem with the returned type of the forkjoin.
Update 2
Turns out removing the tasks$ array and adding the functions directly to the forkjoin solved the problem.
Upvotes: 0
Views: 230
Reputation: 13515
Try converting your nested subscription into a switchMap
.
I have refactored your example to:
resultList
out to some variable or property - that can be used lateruserList
onto a switchMap
switchMap
to forkJoin
all of the calls to getUserDetails
const tasks$ = [
this.getAccounts(),
this.getResults()
];
forkJoin(tasks$).pipe(
tap((value: [ Account[], Result[] ]) => this.resultList = value[1]),
map((value: [ Account[], Result[] ]) => value[0]),
switchMap(accounts => forkJoin(
accounts.map(x => this.getUserDetails(x.access_token))
))
).subscribe(details => {
this.userList = details.filter(x => !!x);
console.log(this.resultList);
});
This example is from my demo below, which demonstrates the concept rather than using your exact calls and setup.
DEMO: https://stackblitz.com/edit/angular-viewbm
Upvotes: 1