Reputation: 2650
I am new to RxJS. Learning observables and subjects. I have a very simple login code divided into two files, a) auth.service.ts and b) login.component.ts
Here is login.component.ts
public login(username: string, password: string): Observable<boolean> {
const headers = { 'content-type': 'application/json' }
const reqBody = {
"userName": username,
"password": password
};
const body = JSON.stringify(reqBody);
const subject = new Subject<boolean>();
this.httpClient.post<IAuthToken>(this.apiUrl, body, { 'headers': headers })
.subscribe(response => {
if (response) {
localStorage.setItem(this.accessTokenKey, response.access_token);
subject.next(true);
}
else {
throwError("Login request failed. Please try again later");
}
},
error => {
// TODO : Code to show invalid username password
// this code throws error. Subscribe in the login.component.ts doesnt receive any error.
throwError(error.error);
});
return subject.asObservable();
}
Here is login.component.ts code
errorMsg: string;
constructor(
private authenticationService: AuthService
) { }
async onLogin(): Promise<void> {
this.authenticationService.login(this.loginForm.value.username,
this.loginForm.value.password)
.subscribe((response) => {
this.errorMsg = null;
if (response)
console.log("logged In");
},
error => {
// TODO : Code to show invalid username password
// This code doesnt execute, i.e. error is not caught.
this.errorMsg = error.error;
console.log(error);
});
}
}
I want to throw error for invalid username password from auth.service.ts and catch it in login.component.ts so that can bind the error to UI. However, the throwError throws error from auth.service.ts, but the error isnt caught in login.component.html
Upvotes: 2
Views: 4242
Reputation: 19764
Several misconceptions here.
Firstly, throwError
is a function which returns an observable that immediately errors. Simply calling it like you do doesn't do anything.
throwError(error.error); // creates an unused observable
Secondly, you're subscribing in the service with some weird glued-together code with a subject. Your service is supposed to just create an observable, and then you subscribe to it in the component. The error would then be caught correctly by default.
// in service
logIn (username: string, password: string): Observable<boolean> {
return this.http.post(api, { username, password })
.pipe(mapTo(true))
}
// in component
onSubmit () {
this.service.logIn('username', 'p@ssword')
.subscribe({
next: () => {
console.log('Success!')
},
error: (error) => {
console.error(error)
}
})
}
throwError
is usually used in conjuction with catchError
when you want to propagate some errors and handle some errors.
return this.http.post(api, { username, password })
.pipe(
catchError((error) => {
if (canHandleError(error)) {
// handle...
return of(false)
} else {
return throwError(error)
}
}),
)
Upvotes: 4
Reputation: 1780
No need to subscribe in service
public login(username: string, password: string): Observable<boolean> {
const headers = { 'content-type': 'application/json' }
const reqBody = {
"userName": username,
"password": password
};
const body = JSON.stringify(reqBody);
return this.httpClient.post<IAuthToken>(this.apiUrl, body, { 'headers': headers })
.pipe(map(response => {
if (response) {
localStorage.setItem(this.accessTokenKey, response.access_token);
return true;
}
}))
}
Upvotes: 1