Reputation: 2445
In my Angular app, I'm getting this error when I try to compile:
Type
'Observable<Promise<void>>'
is not assignable to type'Observable<AuthResponseData>'
. Type 'Promise' is missing the following properties from type 'AuthResponseData': kind, idToken, email, refreshToken, and 2 more
Here is the AuthResponseData
interface:
export interface AuthResponseData {
kind: string;
idToken: string;
email: string;
refreshToken: string;
localId: string;
expiresIn: string;
registered?: boolean;
}
Here is the login() method:
login() {
let authObs: Observable<AuthResponseData>;
authObs = this.authService.login(this.email, this.password);
authObs.subscribe(
resData => {
console.log('Response Data:', resData);
this.router.navigateByUrl('/home');
},
errRes => {
console.log('Error Response:', errRes);
});
}
And here is AuthService.login()
:
login(email: string, password: string) {
return of(firebase.auth().signInWithEmailAndPassword(email, password)
.then((user) => {
console.log('Service User Value', user);
}).catch((err) => {
console.log('Service Error', err);
}));
}
Can someone please tell me what changes I need to make so that I'm assigning the correct type in the Observable?
Upvotes: 0
Views: 301
Reputation: 31125
This is one of the reasons why I don't prefer mixing promises and observables although it isn't a hack or a workaround.
If you still wish to convert the promise to an observable you could do it using RxJS from
(RxJS v6.0.0+). From the docs:
Creates an Observable from an Array, an array-like object, a Promise, an iterable object, or an Observable-like object.
If a then
or a catch
method if provided to the promise, then the from
operator will return an observable of the promise returned by the corresponding method instead of the source promise. It'd be better to remove them when converting.
Try the following
Service
import { from } from 'rxjs';
login(email: string, password: string) {
return from(firebase.auth().signInWithEmailAndPassword(email, password));
}
Component
login() {
let authObs: Observable<any>; // <-- use 'any' instead of a specific type
authObs = this.authService.login(this.email, this.password);
authObs.subscribe(
resData => {
console.log('Response Data:', resData);
this.router.navigateByUrl('/home');
},
errRes => {
console.log('Error Response:', errRes);
}
);
}
Pre RxJS v6.0.0, please refer here.
Upvotes: 1
Reputation: 26
It seems that your login
method returns Promise not Observable, Promise has no subscribe
method. To convert it to Observable you can use from
operator. See that question for details: Convert Promise to Observable
EDIT:
First replace of
with from
to get Observable of response and not Observable of Promise. Then remove catch. It should look something like this:
// in Component
authObs = this.loginService('', '');
authObs.subscribe(
resData => {
console.log('Response Data:', resData);
},
errRes => {
console.log('Error Response:', errRes);
});
}
// In service
public login(email: string, password: string) {
return from(firebase.auth().signInWithEmailAndPassword(email, password));
}
Upvotes: 0
Reputation:
This might solve your problem: Convert Promise to Observable
return firebase.auth().signInWithEmailAndPassword(email, password)
.then((user) => {
console.log('Service User Value', user);
}).catch((err) => {
console.log('Service Error', err);
});
This code returns a promise. You're trying to assign your local Observable to the returned Promise. You first need to convert the promise to an observable with Observable.fromPromise
.
Upvotes: 0