3

I'm looking for a solution to render dynamically some component in my angular application. So I feel the best approche is to look into https://angular.io/guide/dynamic-component-loader but this is not exactly what I'm looking for.

Just a bit of context, let's say your application permit to your users to see offers depending on their profile/eligibility. My application will do some request and at the end you can consider that we are able to build some methods like

isEligibleToFirstOffer() : boolean
isEligibleToSecondOffer() : boolean
isEligibleToThirdOffer() : boolean

Each offer is really specific and have different business logic that we can't just create a generic component with inputs, I would like to separate each offer in his own component to isolate as much as possible the logic by type of offers.

What I want to achieve is to build a OffersWrapper component which take as input an array of component classes and render it in a main container.

This array would be build with the previous logic, something like:

const componentsToRender = [
  ...(isEligibleToFirstOffer() ? [FirstOfferComponent] : []),
  ...(isEligibleToSecondOffer() ? [SecondOfferComponent] : []),
  ...(isEligibleToThirdOffer() ? [ThirdOfferComponent] : [])
]

Now the question is, what is the best approach to give this array to a generic component and make them render dynamically ?

We could also improve a bit the componentsToRender to be able to inject also data, but this is not the main issue of this question, anyway it could be interesting to give a full answer for futur dev who want to take a look at this solution.

const componentsToRender: {component: any, data: any}[]

at the end, the solution would give us the ability to write this kind of code:

<html>
  <body>
    <main>
      <component-wrapper [components]=componentsToRender></component-wrapper>
      <router-outlet></router-outlet>
    </main>
  </body>
</html>

Thanks!

7
  • Vd It’s unclear what you’re looking for. Your html example indicates something known at compile time (structure) - while your question indicates something known only at runtime (when specific user data has been fetched)? Commented Jul 29, 2022 at 22:49
  • Its very unclear what u want... What is dynamic component? Is it just component that one can add in you app source code, then build app and deploy? Or admin of your app can add another component while app is running? Commented Jul 29, 2022 at 23:32
  • @MikeOne that's true, sorry i edited my question. I want something dynamic at runtime, when data are fetched. Commented Jul 30, 2022 at 1:23
  • @PetrAveryanov just from source code, all components are already defined in the codebase, and we want to render them dynamically at runtime. Commented Jul 30, 2022 at 1:24
  • Maybe another explanation why I need that. it's just because I want the OffersWrapper to be responsible of the WHAT is showed in the application, et all the components FirstOfferComponent, SecondOfferComponent ... is about the HOW we display it in the application. Both concern are not the same and I would like to handle them in different places. Commented Jul 30, 2022 at 15:09

1 Answer 1

1

From the question, it appears that you have a set of components and you know what you want to render and for what cases upfront.

If so, then there is not so much dynamic. You can encapsulate everything in a component. The component will decide what to render and when. If needed an additional service could be created to offload decision logic from the component.

Could be as simple as

@Component({
  template: `
  <component-a *ngIf="condition1"></component-a>
  <component-b *ngIf="condition2"></component-b>
  <component-c *ngIf="condition3"></component-c>
`
})
export class Component {
  condition1: boolean;
  condition2: boolean;
  condition3: boolean;

  ngOnInit() {
    this.service.getData().subscribe(res => {
      // set the conditions here
    });
  }
}

If you need to show offers in a queue manner by any chance, then you could make this queue in the ngOnInit.

For example

@Component({
  template: `
  <component-a *ngIf="queue[0] === 'component-a'" (close)="queue.shift()"></component-a>
  <component-b *ngIf="queue[0] === 'component-b'" (close)="queue.shift()"></component-b>
  <component-c *ngIf="queue[0] === 'component-c'" (close)="queue.shift()"></component-c>
`
})
export class Component {
  queue = []; // ['component-a', 'component-b'] for example

  ngOnInit() {
    this.service.getData().subscribe(res => {
      // set the queue here
    });
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.