Search code examples
angularangular-routerangular-oauth2-oidc

After OAuth redirect with hash, Angular SPA doesn't load svg's if next http call fails with Options status 0 conn refused? weird edge case


Normal behaviour

User clicks google icon, get reidrect to google Oauth, successfully logs in, redirected with state details back to the Angular SPA. The SPA processes the hash in the state and takes the access token to make a HTTP request to our own REST endpoint for authentication.

Trigger

If our REST app is down, that request with the access token will fail the OPTIONS request with status 0: Connection Refused and later throw a HTTP Error status 0. That error is handled by the catchError block and the user is notified about it. Problem is handled

The error

Now the weird part is, when the scenario above happens with a redirect from google's OAuth page, the SVG icons I have throughout my app go blank. The buttons still work & show up there, [img] tags work as well, strictly the svg icons.

Now my Oauth login for microsoft is handled with a popup instead of a redirect and when the same scenario fails, the svg definitions are fine.

The SVGs

I have a reusable component as follows:

icon.ts

  location: string;

  constructor(
    @Optional() @Inject(REQUEST) private request: any,
    @Inject(PLATFORM_ID) private platformId: object
  ) {
    if (isPlatformServer(this.platformId)) {
      this.location = this.request.get('host');
    } else {
      this.location = window.location.href;
    }
  }

  @Input() name: string;
  @Input() size: string;

icon.html

<svg
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  [style.width]="size"
  [style.height]="size"
>
  <use
    [style.fill]="color ? color : 'white'"
    [attr.xlink:href]="location + '#' + name"
  ></use>
</svg>

and the definitions themselves are in an empty component loaded in root with display:none

<svg
  version="1.1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
    <symbol id="icon-name" viewBox="0 0 512 512">
<<<<<<actual svg code stuff>>>>>>>
    </symbol>
</defs>
</svg>

Now my best guess is something to do with the way that URL is obtained in icon.ts due to the hash but from what I've tinkred with it I haven't succeeded on making it work.


Solution

  • I'm now splitting the absolute URL to remove everything after a hash starts:

      location: string;
    
      constructor(
        @Optional() @Inject(REQUEST) private request: any,
        @Inject(PLATFORM_ID) private platformId: object
      ) {
        if (isPlatformServer(this.platformId)) {
          this.location = this.request.get('host').split('#')[0];
        } else {
          this.location = window.location.href.split('#')[0];
        }
      }