How can I solve this problem?
Angular CLI: 14.0.2
Node: 16.13.0
rxjs: 7.5.5
typescript: 4.7.4
My imports :
import { Observable, BehaviorSubject } from "rxjs";
import { first, catchError, tap } from "rxjs/operators";
Error on first(),
login(
email: Pick<User, "email">,
password: Pick<User, "password">
): Observable<{
token: string;
userId: Pick<User, "id">;
}> {
return this.http
.post(`${this.url}/login`, { email, password }, this.httpOptions)
.pipe(
first(),
tap((tokenObject: { token: string; userId: Pick<User, "id"> }) => {
this.userId = tokenObject.userId;
localStorage.setItem("token", tokenObject.token);
this.isUserLoggedIn$.next(true);
this.router.navigate(["/"]);
}),
catchError(
this.errorHandlerService.handlerError<{
token: string;
userId: Pick<User, "id">;
}>("login")
)
);
}
CodePudding user response:
Regarding this guide, you specified T as
Observable<{
token: string;
userId: Pick<User, "id">;
}>
Please specify the expected returned value type in post<T>
request and in first<T>
operator as well.
CodePudding user response:
You need to specify the return type of post
so that it matches the return type of the function.
return this.http.post<{
token: string;
userId: Pick<User, "id">;
}>( ... )
.pipe( ... )
The return types within the pipe can be inferred by the compiler, but there is no way to tell the return type of post
without you explicitly stating it.
I'd suggest you make a type so the code isn't so verbose
type TokenAndId = {
token: string;
userId: Pick<User, "id">;
}
login(
email: Pick<User, 'email'>,
password: Pick<User, 'password'>
): Observable<TokenAndId> {
return this.http
.post<TokenAndId>(
`${this.url}/login`,
{ email, password },
this.httpOptions
)
.pipe(
first(),
tap((tokenObject: TokenAndId) => {
this.userId = tokenObject.userId;
localStorage.setItem('token', tokenObject.token);
this.isUserLoggedIn$.next(true);
this.router.navigate(['/']);
}),
catchError(this.errorHandlerService.handlerError<TokenAndId>('login'))
);
}