That's a question about the fundamental things but I don't know how to return back response to the component depending on the action result: success or error, so I can execute related to them actions.
I have a component SignInComponent which collects all necessary information from the form and sends it to my AuthService which handles with my GraphQL requests (and for now redirecting and other things). For a scenario that request is successful, everything works fine so far, but if there is any error response from API I need to have the errors and information about them in my SignInComponent. (if wrong credentials I should inform the user about that and so on)
I tried to return the value like:
signIn.subscribe({
next: // actions for successful response,
error: (err) => {return 'errors'} // from here
})
and also I tried to throw an Error like this:
signIn.subscribe({
next: // actions for successful response,
error: (err) => {throw new Error('Oops')} // The Error
})
and tried to catch it like this in my SignInComponent:
try {
this.authService.signIn(params);
} catch (e) {
// handling the error accordingly
}
But all of that mentioned above didn't help me get response in my SignInComponent and be notified about the result status.
here is my code and I hope someone can tell me how to handle this situation using good practices.
auth.service.ts
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { SignInMutation, SignInInput } from './sign-in.graphql';
import { SignUpMutation, SignUpInput } from './sign-up.graphql';
import { BehaviorSubject } from 'rxjs';
// TODO: To learn if observable is unsubscribed in services automatically. In Classes there is an Inteface OnDestroy for that
@Injectable({
providedIn: 'root'
})
export class AuthService {
auth: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(
private router: Router,
private signInMutation: SignInMutation,
private signUpMutation: SignUpMutation
) {
this.isSignedIn();
}
signIn(params: SignInInput) {
this.signInMutation.mutate(params)
.subscribe({
next: ({ data }) => {
const signIn = data.signIn;
const token = signIn.token;
const { payload } = JSON.parse(atob(token.split('.')[1]));
const currentUser = payload.userData;
const localData = {
currentUser,
token
};
this.setLocalData(localData);
this.router.navigate(['/dashboard']);
this.auth.next(true);
},
error: (err) => {
throw new Error('Ooops...');
}
});
}
signUp(SignUpInput: SignUpInput) {
this.signUpMutation.mutate({ SignUpInput })
.subscribe({
next: console.log,
error: console.log,
});
}
private getLocalData(name: string): null | object | string {
const data = localStorage.getItem(name);
if (!data) { return null; }
if (/^(\{).*(\})$/i.test(data)) {
return JSON.parse(data);
} else {
return data;
}
}
private setLocalData(data: object) {
for (const key in data) {
if (data.hasOwnProperty(key)) {
const value = data[key];
if (typeof value === 'object') {
localStorage.setItem(key, JSON.stringify(data[key]));
} else {
localStorage.setItem(key, data[key]);
}
}
}
}
signOut() {
localStorage.removeItem('token');
localStorage.removeItem('currentUser');
this.router.navigate(['/']);
this.auth.next(false);
}
private isSignedIn() {
const token = this.getLocalData('token') as string;
const checkFormat = (token && token.split('.').length === 3) ? true : null;
if (token && checkFormat) {
this.auth.next(true);
}
}
}
signInComponent
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { AuthService } from '../auth.service';
import { emailFormat } from '../../_helpers/custom-validation';
@Component({
selector: 'app-sign-in',
templateUrl: './sign-in.component.html',
styleUrls: ['./sign-in.component.scss']
})
export class SignInComponent implements OnInit {
signInForm: FormGroup;
submitted: boolean;
constructor(
private fb: FormBuilder,
private authService: AuthService,
) { }
ngOnInit(): void {
this.signInForm = this.fb.group({
email: ['', [emailFormat]],
pwd: [''],
});
this.reset();
}
onSubmit(e) {
e.preventDefault();
this.submitted = true;
if (this.signInForm.valid) {
const params = {
email: this.signInForm.value.email,
password: this.signInForm.value.pwd
};
this.authService.signIn(params);
this.reset();
}
}
private reset() {
this.signInForm.reset();
this.submitted = false;
}
}
Thank you all in advance!