Skip to content

Is there any way to do stratergic loading of component at runtime in Angular?

  • I have this application where I do rest call to a server and receive a JSON response which contains the name of an particular UI setting.
  • Let’s assume the data received from server is as follows,
    Response :-
{
    "uiSetting" : "ui-type-one"
}
  • There can be multiple UI settings like ui-type-two, ui-type-three and so on.
  • Is there any way in angular to decide which component to load at runtime based on this uiSetting value Like following

@Component({
  selector: 'base-strategy',
  templateUrl: './base.component.html',
  styleUrls: ['./base.component.css']
})
export class BaseStrategy {
}


@Component({
  selector: 'ui-type-one-strategy',
  templateUrl: './UiTypeOne.component.html',
  styleUrls: ['./ui-type-one.component.css']
})
export class UiTypeOneStrategy extends BaseStrategy {

}

@Component({
  selector: 'ui-type-two-strategy',
  templateUrl: './UiTypeTwo.component.html',
  styleUrls: ['./ui-type-two.component.css']
})
export class UiTypeTwoStrategy extends BaseStrategy {

}

HTML will be like this.

<!-- If response received is ui-type-one this should show UI of ui-type-one-strategy. 
If response received is  ui-type-two this should show UI of ui-type-two-strategy. and so on.
-->
<base-strategy></base-strategy>

I am aware of ng-template in angular but that I want to use as last option, I am new to angular hence wanted to know if there is any such way to define UI strategy based on response.

Answer

You can create components dynamically using Dynamic Component Loader.

Angular provides the ComponentFactoryResolver which can be used along with ViewContainerRef to dynamically load components.

In your case, maybe based on the response, you can dynamically load the component.

Glimpse of the code:

async load(comp: string) {
    let component: Type<any>;
    switch (comp) {
      case 'A': {
        component = (await import('./comp-a/comp-a.module')).default;
        break;
      }
      case 'B': {
        component = (await import('./comp-b/comp-b.module')).default;
        break;
      }
    }
    const factory = this.cfr.resolveComponentFactory(component);
    this.container?.clear();
    this.container.createComponent(factory);
}

Demo: https://stackblitz.com/edit/angular-ivy-n2zrqt?file=src%2Fapp%2Fapp.component.ts

Docs: https://angular.io/guide/dynamic-component-loader#loading-components

In Angular v13, components can be created without the need for ComponentFactoryResolver. Check out the blog here: https://blog.angular.io/angular-v13-is-now-available-cce66f7bc296