2
votes

Angular 7 Typescript - Service ErrorHandle perd une instance d'objet

J'essaie d'afficher un message d'erreur [ngBootstrap Alert] lorsque j'obtiens 404 ou 500 d'un appel de service api.

Je souhaite afficher une erreur via alertComponent et j'utilise le service de partage de données [AlertService.ts].

Lorsque mon appel à l'API renvoie 404, j'attrape une erreur et j'appelle la méthode handleError qui est définie dans ma classe de base de service.

Le problème est que j'ai injecté mon service d'alerte dans ma classe de base et quand J'appelle la méthode HandleError, la variable alert perd son instance et est définie sur undefined.

BaseService.ts

export class Alert {
  constructor(public alertType: AlertType,
    public msgCode: string,
    public icon?: string) { }
}

export enum AlertType {
  Success = 'success',
  Info = 'info',
  Warning = 'warning',
  Danger = 'danger',
}

ChildService.ts

@Injectable({
  providedIn: 'root'
})
export class AlertService {

  alertMsg: Alert;
  constructor() { }

  public clear() {
    console.log('alert cleared');
    this.alertMsg = null;
  }

  public Add(alert: Alert) {
    this.alertMsg = alert;
  }
}

AlertService.ts

    @Injectable({
      providedIn: 'root'
    })
    export class ChildService extends BaseService {
    constructor(alertService: AlertService){
    super(alertService)
    }

    callApiMethod (){
     return this.http.get<Brand>(`ApiUrl`).pipe(

          catchError(this.handleError)
        );
     }
  }

Alert.ts

@Injectable({
  providedIn: 'root'
})
export abstract class BaseService {

  constructor(msgService: AlertService) { }

  public handleError(httpErrorResponse: HttpErrorResponse) {

    console.log(httpErrorResponse);

    let errorMessage = '';
    switch (httpErrorResponse.status) {
      case 400:
        errorMessage = 'Bad Request detected; please try again later!';
        break;
     case 404:
        const errorMsg = new Alert(AlertType.Danger, 'tracking-not-found');
        this.msgService.Add(errorMsg);
        break;
      case 500:
        errorMessage = 'Internal Server Error; please try again later!';
        break;
      default:
        errorMessage = 'Something bad happened; please try again later!';
        break;
    }
    return throwError(errorMessage);

  }

Quand j'essaye d'appeler Add method from AlertService J'obtiens l'erreur suivante

TypeError: Impossible de lire la propriété 'Add' d'undefined

Je vois que la variable msgService est définie pour undefine d'une manière ou d'une autre. Avez-vous de l'aide?


1 commentaires

Bons extraits de code: pouvez-vous également les mettre à jour avec vos import ?


3 Réponses :


4
votes

Je suppose que votre problème réside dans la non-liaison:

@Injectable({
  providedIn: 'root'
})
export class ChildService extends BaseService {
  constructor(alertService: AlertService){
    super(alertService)
  }

  callApiMethod (){
    return this.http.get<Brand>(`ApiUrl`).pipe(
      catchError(this.handleError.bind(this)) // here we need to either bind or use arrow function
    );
  }
}

C'est si votre erreur est causée par cette ligne dans this.msgService.Add (errorMsg); dans BaseService.


0 commentaires

1
votes

Vous devez définir le spécificateur d'accès du service dans le constructeur de BaseService Class:

constructor(private msgService: AlertService) { }

alors vous seul pourrez faire "this.msgService" et cela ne viendra pas non défini.

Cheers (y)


1 commentaires

Oui, j'ai essayé ceux-là. cela n'a pas fonctionné .. @ Xesenix a obtenu la réponse.



0
votes

Vous devez utiliser un modificateur d'accès (public / privé) dans ChildService et BaseService , afin que votre référence de service soit disponible avec la propriété.

ChildService

 @Injectable({
  providedIn: 'root'
})
export abstract class BaseService {

  constructor(**private msgService**: AlertService) { }

}

BaseService

@Injectable({
  providedIn: 'root'
})
export class ChildService extends BaseService {
constructor(**private alertService**: AlertService){
super(alertService)
}

1 commentaires

Oui, j'ai essayé ceux-là. cela n'a pas fonctionné .. @ Xesenix a obtenu la réponse