Is it permissible to incorporate a snackbar within my service?

I am trying to retrieve error details from a service call that communicates with an API in case of an error occurrence.

For example, if the HTTP error returned is 422, I want to display a user-friendly message.

Below is my service class:

@Injectable()
export class TransactionService {

  private baseUrl = 'http://foo.bar/api';
  private body;
  private headers;
  private options;

  constructor(private http: HttpClient, private snackBar: MatSnackBar) {

  }

  openSnackBar(message: string) {
    this.snackBar.open(message, null, {duration: 5000});
  }

  errorHandler(error: HttpErrorResponse) {

    console.log(error.status);
    if (error.status === 422) {
      this.openSnackBar('Number already exists');
    } else {
    return Observable.throw(error.message || 'Server Error');
    }
  }

  SubmitTransaction(transactionRequest: ITransactionRequestObj): Observable<TransactionResponse> {
    this.body =  JSON.stringify(transactionRequest);
    this.headers = new HttpHeaders().set('Content-Type', 'application/json');
    this.headers.append('Accept', 'application/json');
    this.options = new RequestOptions({headers: this.headers});
    console.log(JSON.stringify(transactionRequest));
    return this.http.post<TransactionResponse>(this.baseUrl + '/transactions/new',  this.body, this.options)
                .catch(this.errorHandler);
  }

}

While I can see the correct error status number when a 422 error occurs, I encounter an issue where the snackbar doesn't pop up. The following error is displayed instead:

core.js:1448 ERROR TypeError: this.openSnackBar is not a function
    at CatchSubscriber.TransactionService.errorHandler [as selector] (transaction.service.ts:49)
    at CatchSubscriber.error (catchError.js:105)
    at MapSubscriber.Subscriber._error (Subscriber.js:131)
    at MapSubscriber.Subscriber.error (Subscriber.js:105)
    at FilterSubscriber.Subscriber._error (Subscriber.js:131)
    at FilterSubscriber.Subscriber.error (Subscriber.js:105)
    at MergeMapSubscriber.OuterSubscriber.notifyError (OuterSubscriber.js:24)
    at InnerSubscriber._error (InnerSubscriber.js:28)
    at InnerSubscriber.Subscriber.error (Subscriber.js:105)
    at XMLHttpRequest.onLoad (http.js:2283)

This makes me wonder if using a snackbar inside a service is not recommended or even possible, and only components are suitable for it?

The same snackbar code works without issues within my component, although I face difficulty accessing the error status within the component. Here's the service call snippet from my component class as well:

this._transactionService.SubmitTransaction(this.transactionObj).subscribe(data => {
        if (data._errorDetails._status === '201') {
          // perform specific action 
        }
      }, (err) => {
        console.log(err);
        if (err.status === 422) { //attempted this within my component but err.status turns out to be undefined. However, the error message from the server is present in err.
        //perform another action 
        }
      });

Answer №1

To ensure that it works correctly, you'll need to bind the correct this context:

.catch(this.errorHandler.bind(this));

Alternatively, you can consider these options as well:

.catch((e) => this.errorHandler(e));

or create a local fat arrow function:

errorHandler = (error: HttpErrorResponse) => {
  ...
}

For more information, please refer to:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Internationalization of deferred-loaded modules within the JHipster application

I created My App using JHipster, which utilizes the JhiLanguageService in the ng-jhipster library. This service relies on the JhiConfigService to configure ngx-translate without requiring manual imports and configuration of the TranslateModule in my app.mo ...

Generate a series of HTTP requests using an HTTP interceptor

Is it possible to initiate an http request before another ongoing http request finishes (For example, fetching a token/refresh token from the server before the current request completes)? I successfully implemented this functionality using Angular 5' ...

Error encountered while building with Next.js using TypeScript: SyntaxError - Unexpected token 'export' in data export

For access to the code, click here => https://codesandbox.io/s/sweet-mcclintock-dhczx?file=/pages/index.js The initial issue arises when attempting to use @iconify-icons/cryptocurrency with next.js and typescript (specifically in typescript). SyntaxErr ...

Is there a way to retrieve keys of the object from this combination type?

Can someone please help me understand how to retrieve keys from this union type? The Value is currently being assigned as a never type. I would like the Value to be either sno, key, or id type Key = { sno: number } | { key: number } | { id: number }; typ ...

The error message "Property 'then' is not available on type 'void' within Ionic 2" is displayed

When retrieving data from the Google API within the function of the details.ts file, I have set up a service as shown below. However, I am encountering a Typescript error stating Property 'then' does not exist on type 'void'. this.type ...

The reason why Class-validator doesn't handle fields that lack a decorator in Nest js

After creating a DTO for my endpoint, I encountered an issue where the class-validator stops checking a field if it doesn't have a decorator assigned to it. Even though I need the field to be mandatory and checked, it gets skipped. DTO: import {IsNum ...

Tips for altering text size within Angular Material form fields with floating placeholder

Looking to customize the font size of the placeholder text in an Angular Material form field? You can set two different font sizes: one for when the placeholder is normal and one for when it floats. Here's how you can achieve this: <mat-form-fiel ...

Tips for adding temporary text in filter input of Kendo UI Grid using Angular

I'm currently working with Kendo UI Grid in conjunction with Angular, and I am struggling to find a solution for adding text or a placeholder in filter inputs using Typescript. Within my code, I am utilizing the kendoGridFilterCellTemplate: <kend ...

Displaying stack traces in a request using HttpInterceptor in Angular 9

I have created an HttpInterceptor and I would like to print the stack trace of the functions involved in making the request for development purposes: import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, ...

The connection between Parent and Child components within the Angular framework

Can changes made in a Child component automatically reflect in the Parent component when passing variables from parent to child? If we send any variable from parent to child and then make changes in the Child component, will these changes be automatica ...

Leverage Sinon's fakeServer in combination with promises and mocha for efficient

Having an issue here: I need to test a method that involves uploading data to an AWS S3 bucket. However, I don't want the hassle of actually uploading data each time I run my tests or dealing with credentials in the environment settings. That's w ...

The classification of rejected promises in Typescript

Is it possible to set the type of rejection for a promise? For example: const start = (): Promise<string> => { return new Promise((resolve, reject) => { if (someCondition) { resolve('correct!'); } else { ...

Next.js: Importing from a new endpoint triggers the code execution once more

Here is a simplified example I created for this specific question. Imagine I want to maintain a server-side state. components/dummy.ts console.log('initialize array') let number: number = 0 const incrementValue: () => number = () => numbe ...

Guide on incorporating secondary endpoints to develop an API for an Angular library

Challenge: I recently developed a customized UI library using ng-packagr, where I exported unique components along with some model classes. Issue: While the import statement functions correctly for the exported components in my main project, it fails to ...

What is the best way to determine the appropriate version of angular/common needed to fulfill the dependencies?

After deploying my changes to the master branch, the pipeline encountered a failure. It seems that there is a version conflict for @angular/common required by different dependencies in the project. The main project requires @angular/common@"^16.0.0&qu ...

Implementing Observable in NativeScript with TypeScript - A Step-by-Step Guide

Recently, I delved into the world of native-script framework and decided to dive into the "Get Started with JavaScript" tutorial provided on their official website. My background in Java has made me more comfortable with typescript, so I attempted to swap ...

`The validation in Angular 12 is successful, yet the mat-input remains invalid.`

Code snippet of Component- ngOnInit(): void { this.form = this.fb.group({ currentPassword: ['', [Validators.required], [this.matchCurrentPassword]], newPassword: ['', [Validators.required, Validators.minL ...

Problems encountered while starting npm in Angular 13

Versions -> PS C:\Users\user> npm --version 8.8.0 PS C:\Users\user> node --version v16.15.0 Executing the following command-> npx -p @angular/cli ng new JokeFrontB After that, I run Serve -> npm start and encountered t ...

Is the environment file in Angular adequately protected from potential breaches?

Currently utilizing Angular 15, I have included confidential information such as passwords and secret keys for encryption in the environment file. My concern is not about the security of the environment file in the repository (such as git or etc), but rath ...

The Microsoft.Azure.WebJobs.Script encountered an issue while attempting to cast an object of type 'System.String' to type 'Microsoft.AspNetCore.Http.HttpRequest' during the return process

I recently encountered an issue with my Azure Function written in JS that is triggered by the Service Bus and generates files to Blob Storage. When attempting to return an HTTP result, I received the following error message: System.Private.CoreLib: Except ...