简体   繁体   中英

What is the best practice when returning errors in angular

I've an angular application. In this application I've an AuthService . This AuthService login one user against the firebase auth.

My question is the following:

Do you think it's the responsability of the service to navigate to a success page if logged successfully? Or should it be the component calling the service?

And if there is an error(like invalid password in my case), how would you return this information to the component to display it to the user?

My service:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { auth } from 'firebase/app';
import { AngularFireAuth } from '@angular/fire/auth';
import { User } from 'firebase';

@Injectable({
    providedIn: 'root'
})
export class AuthService {
    user: User;
    constructor(public afAuth: AngularFireAuth, public router: Router) {
        this.afAuth.authState.subscribe(user => {
            if (user) {
                this.user = user;
                localStorage.setItem('user', JSON.stringify(this.user));
            } else {
                this.user = null;
                localStorage.setItem('user', null);
            }
        });
    }

    async login(email: string, password: string) {
        let result = await this.afAuth.auth.signInWithEmailAndPassword(
            email,
            password
        );
        this.router.navigate(['...']); 
    }
}

My component:

import { Component } from '@angular/core';
import { AuthService } from '../auth.service';
import { NgForm } from '@angular/forms';

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.css']
})
export class LoginComponent  {

    constructor(private authService: AuthService) { }

    onSubmit(form: NgForm) {
        this.authService.login(form.value.email, form.value.password);
    }

}

To answer for your question

Do you think it's the responsability of the service to navigate to a success page if logged successfully? Or should it be the component calling the service?

For clean code respective I think you need to handle navigate logic in the service because from time to time your component will growth and your code base is very hard to maintain. Or I would suggest you take a research on NGRX library they have 1 layer call effect so you can do side effect logic for your app in there and the service class only do calling API.

And if there is an error(like invalid password in my case), how would you return this information to the component to display it to the user?

Same as my option above. And would suggest you go for side effect approach because API error will be handle inside effect class too

Below is the sample of my app. When I received success login action I will redirect user login to portal page. To fully understand this pattern you can take a look at this picture

在此处输入图片说明

A component is dispatch an action. Action will be handle by effect if we need to some side effect (like in this example is redirect user to poratal page if they login success). Then the reducer will calculate new state base on action type and the data coming from component or effect side then it will update the UI to reflect the change.

@Effect({dispatch: false})
  loginSuccess$ = this
    .actions$
    .pipe(ofType(authAction.LoginActionTypes.LOGIN_SUCCESS), tap(() => this.router.navigate(['/portal'])));

You can take a look of my full sample here and NGRX lib

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM