aurelia / cli

The Aurelia 1 command line tool. Use the CLI to create projects, scaffold components, and bundle your app for release.
MIT License
407 stars 133 forks source link

Importing the 'aurelia-router' into an ApiInterceptor Breaks Application #1187

Closed CollinHerber closed 3 years ago

CollinHerber commented 4 years ago

I'm submitting a bug report

Please tell us about your environment:

Current behavior: When importing the aurelia-router into an ApiInterceptor nothing loads. There is no errors or warnings of any sort, just a blank white page when trying to load the application.

Code Examples main.js

aurelia.container.get(HttpClient).configure(config => {
        config
            .withBaseUrl(environment.apiEndpoint)
            .withInterceptor(aurelia.container.get(ApiInterceptor))
            .withDefaults({
                headers: {
                    'Accept': 'application/json'
                }
            });
    });

ApiInterceptor.js

import { inject } from 'aurelia-framework';
import { Router } from 'aurelia-router'';

@inject(Router)
export class ApiInterceptor {
     constructor(router) {
          this.router = router;
    }
}

With the router imported, it does not work. Without the router imported everything works as expected.

3cp commented 4 years ago

Sounds unlikely a bundler issue. Can you test in webpack env too?

CollinHerber commented 4 years ago

Sounds unlikely a bundler issue. Can you test in webpack env too?

If someone wants to test a cli generated webpack project for this same error , be my guest. I don't have time for that unfortutely.

3cp commented 4 years ago

Since you created the issue here, I thought you assume this is a bundler bug, hence my suggested investigation.

I had another look, and I think I figured out what went wrong.

When using DI with Router, there is small difference than other classes.

The shared instance of Router is only created by the time Aurelia loads first configureRouter (normally in app.js).

Your code uses DI for ApiInterceptor before start() (start will load router sequentially), that means DI could not find the instance for Router at the time you code runs. I guess DI is trying to create another generic singleton for Router here, but the created singleton does not play well in aurelia app, because Router is not designed in generic way.

A possible fix of your code is to delay the initialization of http client, make it after router was loaded.

Yes, aurelia DI probably could improve the error message for premature Router instance. cc @bigopon

3cp commented 4 years ago

Have you found a solution?

3cp commented 3 years ago

Pls reopen if needed.