2

I have a custom RxJs function that handles exceptions from http calls which looks like following (simplified)

export default function applicationRxJsExceptionHandler<U>(defaultOutputValue: U = null, defaultErrorMessage: string = 'Error occured, requested operation has not been executed', logToConsole: boolean = true) {
    return function <T>(source: Observable<T>) {
        return source.pipe(catchError((err: ProblemDetails | ValidationProblemDetails | any) => {
            if (err instanceof ValidationProblemDetails) {                   
                var errorDialogService = GlobalAppInjector.get(ValidationErrorDialogService);
                errorDialogService.ShowValidationErrorDialog(err).subscribe(_ => { });

            } else if (err instanceof ProblemDetails) {
                //... other code here
            }
            else {
                //.. other code here                   
            }

            if (logToConsole)
                console.log(err);

            return of(defaultOutputValue);
        }))
    }
}

As this default function does not have a constructor, which I could use to inject my ValidationErrorDialogService, and also I did not want to insert it as a separate parameter (as number of services can grow over time), I did the following:

in my app.component.ts I created a new global variable

export let GlobalAppInjector: Injector;

And then, within the same app.component, I injected Angular Injector in constructor and populated my global variable as following:

export let GlobalAppInjector: Injector;

@Component({
  selector: 'skeleton-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {

  constructor(private injector: Injector){
    GlobalAppInjector = this.injector;
  }
}

The reason why I went for this solution was, that I was unable to access already existing Injector directly from my custom function. What I don't like about this is, that I have just created a dependency in my app.component, only for the sole purpose of my custom function which seems like an overkill.

I am sure that there should be a better way how to do it. Any help in respect to this matter would be highly appreciated.

1 Answer 1

2

Instead of trying to register the Injector globally, I'd instead recommend that you take in the injector as an argument to your RxJs operator.

It's a much cleaner approach, and unit testeable.

Sign up to request clarification or add additional context in comments.

2 Comments

If you absolutely wanted to pollute your global scope, you could assigned the injector instance to the window-object, but I would not recommend it.
I was trying to completely avoid using global variables, however Injecting Injector directly into service is great approach that I did not think of. thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.