0

I'm building an angular app and I want to load my components only when that route has been requested. I thought something like this might work

const states = [{
    name: 'login',
    url: '/login?sessid',
    component: 'login',
    resolve: {
      login: () => import('./components/login.js').then(login => {
        login.default.register()
      }),
    },
}];

Where the login component is

export default {
      register() {
        angular.module('trending')
          .component('login', () => ({
              template: 'Hello!'
            })
        )
    }
};

But I get an error

angular.js?10a4:13708 Error: [$injector:unpr] Unknown provider: 
loginDirectiveProvider <- loginDirective

Presumably because the login component isn't registered before the state is. I realize that this is abusing the purpose of the resolve property, I just hoped it would work for my needs. What's a better way to fix this?

2

1 Answer 1

3

After the app gets bootstrapped, you can't declare a component anymore. So, in order to register a component at run time, you have to expose, somehow, the respective factories. The code bellow exposes all factories on the main app module, but you can use only the component's if you prefer.

const app = angular.module('trending', []);

app.config(($controllerProvider, $compileProvider, $filterProvider, $provide) => {
    app.register = {
        component: $compileProvider.component,
        controller: $controllerProvider.register,
        directive: $compileProvider.directive,
        filter: $filterProvider.register,
        factory: $provide.factory,
        service: $provide.service
    };
});

This way, you just have to call app.register.component to access the exposed factory. For example, taken from your question:

export default {
      register() {
        angular.module('trending')
          .register
          .component('login', () => ({
              template: 'Hello!'
            })
        )
    }
};

You might find a fancier way to register your modules, this is just a demonstration for the sake of the answer, you can either change the nomenclature used or even the exposing mechanism to fit better on your fancy es6+ components.

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

Comments

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.