0

Following an article on Angular 2 Custom http service here: which also leverages another custom http error service to handle http error codes and reload screen, Code for this service is here:

@Injectable()
export class HttpErrorHandler {

    constructor(
        private apiGateway: ApiGateway
    ) {
        apiGateway.errors$.subscribe(
            (value: any) => {
                console.group("HttpErrorHandler");
                console.log(value.status, "status code detected.");
                console.dir(value);
                console.groupEnd();
                // If the user made a request that they were not authorized
                // to, it's possible that their session has expired. Let's
                // refresh the page and let the server-side routing move the
                // user to a more appropriate landing page.
                if (value.status === 401) {
                    window.location.reload();
                }
            });
    }
}

What I am trying to achieve is on 401 error redirect to login route using:

router.navigate(['Login']);

However, when I inject Router service in HttpErrorHandler service I get some injection errors.

Error: EXCEPTION: Error during instantiation of Token RouterPrimaryComponent! (Token Application Initializer -> HttpErrorHandler -> Router -> RouteRegistry -> Token RouterPrimaryComponent)

Note: Above HttpErrorHandler is configured during bootstrap phase of application like this:

bootstrap(AppComponent, [
    HTTP_PROVIDERS,
    ROUTER_PROVIDERS,
    ApiGateway,
    FriendService,
    HttpErrorHandler,
    //
    // Make sure our "unused" services are created via the
    //  APP_INITIALIZER token
    //
    provide(APP_INITIALIZER, {
        useFactory: (httpErrorHandler) => {
            console.info( "HttpErrorHandler initialized." );
        },
        deps: [HttpErrorHandler]
    })
]);

Not sure if I am injecting Router service quite early in the application lifecycle. Is there any way to inject Router service in HttpErrorHandler service so that client side navigation can be used?

I have created a plnkr here showing the error as well.

Nexus23
  • 6,195
  • 9
  • 50
  • 67

1 Answers1

2

This code is the cause:

provide(APP_INITIALIZER, {
    useFactory: (httpErrorHandler) => {
        console.info( "HttpErrorHandler initialized." );
    },
    deps: [HttpErrorHandler]
})

"Bootstrap at least one component before injecting Router"

Factory instantiates HttpErrorHandler and Router as its dependency before AppComponent.

kemsky
  • 14,727
  • 3
  • 32
  • 51
  • Not sure what do you mean by at least one component, when HttpErrorHandler factory needs initalizing during bootstrap. Can you try your idea on the plnkr given above please? Thanks – Nexus23 Apr 18 '16 at 22:29
  • This is error message from your plunkr, it tells that you try to instantiate `Router` before any `Component`. You do not need to create `HttpErrorHandler` that early, it will be created automatically when needed. Just remove this code. [plunkr](http://plnkr.co/edit/GWuvkAZBawsGuLmf40JN?p=preview) – kemsky Apr 18 '16 at 22:35
  • I think you didn't understand the problem and details mentioned in question above. Its not about removing HttpErrorHandler during initialization. We can initialized customised factories during bootstrapping, not at the component level. The problem to get HttpErrorHandler available at application level to handle http related errors is a perfect solution as mentioned in the article in question. The only thing I wanted to achieve was to use: router.navigate(['Login']); <= this requires Router service availble in HttpErrorHandler service (this is my problem). instead of window.location.reload(); – Nexus23 Apr 19 '16 at 08:14
  • this is workaround: [plunkr](http://plnkr.co/edit/GWuvkAZBawsGuLmf40JN?p=preview) – kemsky Apr 19 '16 at 09:18
  • Doesn't work. httperrorhandler isn't even being called now. I think it has to be registered with APP_INITIALIZER token during bootstrap. – Nexus23 Apr 19 '16 at 10:52
  • in fact it does, press `Load Friend 4 (Not Found) ` and check console. i've changed code to 404 for testing. – kemsky Apr 19 '16 at 10:55
  • Indeed it works, Thanks @kemsky. Strage thing is I can see this in plnkr but same code in my application doesn't work. For now I have created a custom httphandler method called when an error occurs in apiGateway service. Simple and sweet. Thanks again :) – Nexus23 Apr 19 '16 at 13:38