When overriding the ExceptionHandler, a cyclic dependency may occur

Here is the code snippet I am working with:

import {Injectable, ExceptionHandler, SkipSelf, Host, Optional} from     '@angular/core';
import {ToastNotification} from '../toast-messages/toastNotification.service';

export class UIError extends Error {
    constructor (private toastMessage: string) {
        super();
        this.toastMessage = toastMessage;
    }
}

export class MyUIError extends UIError {}
export class AnotherError extends UIError {}

export class _ArrayLogger {
    res = [];
    log(s: any): void { this.res.push(s); }
    logError(s: any): void { this.res.push(s); }
    logGroup(s: any): void { this.res.push(s); }
    logGroupEnd() {};
}

export class ConsoleLogger {
    log(s: any): void {console.log(s);}
}

@Injectable()
export class CustomExceptionHandler extends ExceptionHandler {
    constructor(private logger: ConsoleLogger, private toast: ToastNotification) {
        super (new _ArrayLogger(), true);
    }

    call(exception: any, stackTrace = null, reason = null) {
        let self = this;
        if (exception.originalException instanceof UIError) {
            self.toast.Error(exception.originalException.toastMessage);
        } else {
            this.logger.log(exception);
        }
    }
}

However, I encountered an issue when attempting to run this code related to the ToastNotification component. The error message received was:

zone.js:260Uncaught EXCEPTION: Error during instantiation of ApplicationRef_! (ApplicationRef -> ApplicationRef).
ORIGINAL EXCEPTION: Cannot instantiate cyclic dependency! (ExceptionHandler -> ToastNotification)
ORIGINAL STACKTRACE:
Error: DI Exception
    at CyclicDependencyError.BaseException

In addition, this component is also injected in the bootstrap configuration. Any suggestions on how to resolve this problem?

Answer №1

Even after trying to use the injector in the constructor, I was still facing the same issue. However, I managed to resolve it by moving the injection part to the call function.

@Injectable()
export class AppExceptionHandler extends ExceptionHandler {
  private router:Router;
  private toaster:ToastsManager;

  constructor(private injector: Injector) {
    super(new _ArrayLogger(), true);
  }

  call(exception:any, stackTrace?:any, reason?:string):void {
    this.getDependencies();
    console.log(exception);

    if(exception.status === 401){
      // Show login
      this.router.navigate(['/login']);
    }

    // Get error messages if http exception
    let msgs = [];
    if(exception instanceof Response){
      msgs = this.getMessagesFromResponse(exception);
    }else{

      // Otherwise show generic error
      msgs.push('Something went wrong');
    }

    // Show messages
    msgs.forEach((msg) => this.toaster.error(msg));

    super.call(exception, stackTrace, reason);
  }

  private getDependencies(){
    if(!this.router){
      this.router = this.injector.get(Router);
    }
    if(!this.toaster){
      this.toaster = this.injector.get(ToastsManager);
    }
  }

}

Answer №2

Upon encountering the query How to Incorporate my Service into ExceptionHandler, it appears that this could serve as a viable solution for your issue. Assuming control over one of the classes in the circular dependencies, you can simply introduce the Injector into the constructor and then retrieve the specific instance you require:

constructor(injector:Injector) {
  setTimeout(() => this.someService = injector.get(SomeService));
}

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

Using React.useContext in a Class Component with Typescript: Issue resolving the signature of the class decorator

Struggling to implement a store using React.createContext within my class components. The setup of my App is as follows: const someStore = new SomeStore(); export const StoreContext = React.createContext(someStore); export interface IProps { store ...

What is the recommended way to handle passing props to child components in React - should all props be passed down, or only specific props

When it comes to passing props to child components, which approach is more efficient: Method 1. Utilize {...props} to pass all props, for example: ParentComponent = (props) => { return <ChildComponent {...props}> } Method 2. Explicitly pa ...

Tips for creating a mapped type in TypeScript that is based on an array

Is there a way to create a function with dynamic properties? function magic(...propertyNames:string[]): { ????? : any } { .... } Could the returned type have properties listed in propertyName? For instance: type ResultType = {alpha:any, bravo:any}; le ...

Tips for obtaining the output of an asynchronous function that contains a query within a loop

I am facing an issue where I need to retrieve a value after the completion of a for loop that is nested within an asynchronous function. The loop contains a query that inserts data into a database. The function seems to be functioning correctly, but when ...

What is the most effective method for extracting an html text element from a website and saving it to the clipboard?

Every day, I find myself having to manually copy text data from the same website. This task is quite tedious and I dream of a solution where I can simply enter the website, specify a particular element by XPath, and have any text within that element automa ...

Guide to duplicating an angular component twice on a single webpage without needing to share variables or validation

I am facing an issue with an address component that needs to be displayed in two different spots on the same page. The component includes a street/building identifier element. <label for="StreetNumber">Husnummer</label> <input id="StreetNum ...

Using jQuery's .html() method to update the inner HTML of an element can cause the .click() event on a form button to stop functioning

There is a puzzling issue with my HTML form button and jQuery functionality. The button is supposed to trigger a .click() event from a JavaScript file, and it was working perfectly until I used jQuery .html() to replace the main page content with the form ...

Using match.params.id in React Router v6: A step-by-step guide

Issue: Uncaught TypeError: Unable to access properties of undefined (reading 'path') at matchPath (utils.ts:622:1) useEffect(() => { const fetchData = async () => { const { info } = await axios.get(`/api/notes/${match.params.id} ...

How can one break down enum values in typescript?

I've defined an enum in TypeScript as shown below: export enum XMPPElementName { state = "state", presence = "presence", iq = "iq", unreadCount = "uc", otherUserUnreadCount = "ouc", sequenc ...

Angular frontend failing to send authorization cookie for cross-origin requests, despite using withCredentials

Today, I've been facing a persistent issue that I just can't seem to figure out. I have my Angular frontend running on localhost:4200 and a Spring Boot backend on localhost:8080. When I call the localhost:8080/api/login endpoint from my Angular ...

Moodle version 3.0 is experiencing issues with loading CSS and Javascript due to compatibility issues with NGINX requests not matching the actual paths

Here is my current configuration: Operating System: Ubuntu 14.04 Web Server: Nginx 1.4.6 PHP Version: 5.5.9 Moodle Version: 3.0 After successfully installing Moodle 3.0 through the browser, none of the CSS or JavaScript files are loading. The error logs ...

An object that holds CSS attributes

I am working on a function that takes an element from the page and adds CSS styles to its attribute. The argument passed to this function should ideally be an object with keys like height, minWidth, flexDirection, and so on. function addStyle (el: HTMLElem ...

Differentiating between web sockets on a server

Setting up a server with clients has presented a challenge. Each client is equipped with a websocket and a web worker, while each worker also boasts its own websocket connection to the server. The issue at hand lies in a particular area of the server where ...

What is the best way to create a countdown timer with React

I've been attempting to create a countdown timer using React. The goal is to count down from 10 to 0 and then trigger a function once it reaches 0. After some searching, I came across an example that seemed ideal for me: https://codesandbox.io/s/0q45 ...

Encrypt with AES in TypeScript and decrypt in Go programming language

Looking for assistance with encrypting data in TypeScript and then decrypting it in Go. The issue I'm facing is that the output in Go does not match the input in TypeScript. What could be causing this discrepancy? Below is my TypeScript code: import ...

Issue with MongoDB aggregate() - receiving error message: "TypeError: Cannot execute forEach method on undefined"

Here is the script I have in "script.js" conn = new Mongo(); db = conn.getDB("learn"); db.contracts.aggregate([ { $match: { regionCode: '77' } }, { $unwind: '$products' }, { $project: { _id: '$_id', r ...

Guide on resetting the scrollHeight values of DOM elements obtained using ClientFunction

I am currently using TestCafe to run tests in two separate fixtures and classes for different app pages. I have noticed that when I use the "ClientFunction" to access the "window.document" object in these tests, the values can vary depending on the executi ...

HTML5 provides seamless transitions for videos

Interested in implementing the HTML5 video tag and JavaScript to achieve a seamless video transition, similar to a cut in a movie. I have reviewed the API at http://www.w3.org/TR/html5/video.html#tracklist If anyone has any suggestions, I would greatly ap ...

Can jQuery Autocomplete function without stopping at white spaces?

Is there a way to modify jQuery UI autocomplete so that it can handle multiple words instead of terminating with a space? For example, if you input "New York City", it should still filter results based on each word. $.ajax({ type: "GET" ...

Occasionally, the button responds to my touch, but other times it remains unresponsive

Issue: I am facing a problem while working on a project that involves React and Firebase integration. Whenever I press the button in my React application, sometimes it adds the data to Firebase successfully, but other times it doesn't work at all. I ...