Это вопрос о фундаментальных вещах, но я не знаю, как вернуть ответ на компонент в зависимости от результата действия: success
или error
, чтобы я мог выполнять связанные с ними действия.
У меня есть компонент SignInComponent, который собирает всю необходимую информацию из формы и отправляет ее в мой AuthService, который обрабатывает мои запросы GraphQL (и на данный момент перенаправление и другие вещи). Для сценария, в котором запрос выполняется успешно, пока все работает нормально, но если есть какой-либо ответ об ошибке от API, мне нужно иметь ошибки и информацию о них в моем SignInComponent. (если введены неверные учетные данные, я должен сообщить об этом пользователю и т. д.)
Я попытался вернуть значение, например:
signIn.subscribe({
next: // actions for successful response,
error: (err) => {return 'errors'} // from here
})
, а также попытался выдать ошибку, подобную этой:
signIn.subscribe({
next: // actions for successful response,
error: (err) => {throw new Error('Oops')} // The Error
})
и попытался поймать это в моем SignInComponent следующим образом:
try {
this.authService.signIn(params);
} catch (e) {
// handling the error accordingly
}
Но все вышеперечисленное не помогло мне получить ответ в моем SignInComponent и получить уведомление о результате status.
Вот мой код, и я надеюсь, что кто-нибудь подскажет мне, как справиться с этой ситуацией, используя хорошие практики.
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;
}
}
Спасибо всем заранее!