Angular 4 - Seeking clarification on the usage of *ngComponentOutlet

When using *ngComponentOutlet, the following code snippets are employed to handle the displaying:


Below is a snippet of functional code:

this.displayComponent({
        'objects':[
                {component: ToDisplayAComponent, expanded: false},
                {component: ToDisplayBComponent, expanded: false}
                ]
    })

The array of objects will be iterated using *ngFor to display the components.

The desired functionality - passing different instances of the same abstract component initialized with unique properties - is not working as shown below:

let compA = new ToDisplayAComponent(aProperty);
let compB = new ToDisplayAComponent(anotherPropert);
this.displayComponent({
            'objects':[
                    {component: compA, expanded: false},
                    {component: compB, expanded: false}
                    ]
        });

In addition to a solution to the issue at hand, I am curious about why the above code does not function correctly.

PS. It compiles but throws the following error message:

ERROR Error: No component factory found for [object Object]. Did you add it to @NgModule.entryComponents?

Answer №1

The Angular compiler scans the components specified in the entryComponents array of the @NgModule and generates factories for them. The ngComponentOutlet directive then utilizes the componentFactoryResolver to retrieve these factories and instantiate component objects. Below is an excerpt from the source code highlighting this process:

@Directive({selector: '[ngComponentOutlet]'})
export class NgComponentOutlet implements OnChanges, OnDestroy {
  @Input() ngComponentOutlet: Type<any>;

  ngOnChanges(changes: SimpleChanges) {
    ...
const componentFactory=componentFactoryResolver.resolveComponentFactory(this.ngComponentOutlet);
this._componentRef=this._viewContainerRef.createComponent(componentFactory,...)

If your first example is functioning correctly, it suggests that you have added both ToDisplayAComponent and ToDisplayBComponent to the entry components list as shown below:

@NgModule({
   entryComponents: [ ToDisplayAComponent, ToDisplayBComponent ]

In this scenario, when the componentOutlet requests a component like so:

resolveComponentFactory(this.ngComponentOutlet)

The variable this.ngComponentOutlet holds a reference to the class ToDisplayAComponent, aligning with the entries defined in entryComponents:

entryComponents[0] === this.ngComponentOutlet (ToDisplayAComponent)

However, in your second example, instead of passing class references, you are passing instances which do not correspond:

entryComponents[0] !== this.ngComponentOutlet (new ToDisplayAComponent())
                                              ^^^^^

This mismatch causes Angular to report an error stating no component factory was found in the entry components.

Your intention to pass custom parameters directly to the component class constructor cannot be achieved in this manner. This is because components are instantiated within the dependency injection context. If you need to pass specific data to a component, consider defining a provider instead.

For further insights on working with dynamic components, you can refer to this article: Here is what you need to know about dynamic components in Angular

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Special react-hook designed for dynamically assigning CSS classes

I'm currently exploring React's hooks and playing around with reusing the ability to add a shadow to an element (utilizing bootstrap as the css-framework). Here is the current structure of my App: export const App: React.FunctionComponent<IA ...

Observing the World with TypeScript

Sorry, I am quite new to this and facing a bit of confusion. So, I have a CalendarService which includes a method called getYear(id: string). The structure of my Year model is as follows: export class Year { id: string; number: Number; months: ...

Ensuring Mongoose Schema complies with an external API

My database schema includes a mongoose User schema with the following structure: const User: Schema = new Schema({ // some other fields email: {type: String, unique: true, require: true, validate: [myValidator, 'invalid email provided'], // some ...

Navigate to the identical component using Angular

There is a situation where a user visits /details;id=1. In the DetailsComponent, there is a table displaying similar objects with a button that redirects to /details;id=x, where x represents the id of the object. After clicking on the button, the URL para ...

Having trouble getting the npm package with @emotion/react and vite to function properly

Encountering an issue with the npm package dependencies after publishing, specifically with @emotion/react. This problem arose while using vite for packaging. Upon installing the package in another project, the css property appears as css="[object Ob ...

Date selection feature in Material UI causing application malfunction when using defaultValue attribute with Typescript

Recently, I discovered the amazing functionality of the Material UI library and decided to try out their date pickers. Everything seemed fine at first, but now I'm facing an issue that has left me puzzled. Below is a snippet of my code (which closely ...

Develop an Angular application and deploy it on an IIS server

I've been facing issues while trying to deploy my Angular app on IIS. After researching, I found that using the cli command ng build resulted in errors such as Module not found. Interestingly, when I modified the templateUrl in the component, the erro ...

Angular 2 component stays static despite changes in route parameters

So, I am in need of a way to refresh my component after the URL parameter's id has been altered. The following code is from my player.component.ts: import {Component, OnInit, AfterViewInit} from '@angular/core'; import {ActivatedRoute, Rout ...

"Exploring the relationship between Typescript and Angular: transforming variables within different

Ever since I made the switch from JavaScript to TypeScript (Version 2.1.5), I have been facing an issue with the code that filters date selection. Despite my efforts, I haven't been able to find a good fix for it yet. Here are the two date-pickers: F ...

Do Typescript interfaces check method parameters for validation?

interface optionsParameter { url: string; } function DEC(options: optionsParameter){ } DEC(2) //typescript check compilation error let obj:any = { name: "Hello" } obj.DEC = function(options: optionsParameter){} obj.DEC(1); // no compilation ...

NGRX Store: struggling to retrieve value from store

Currently, I am working on setting up a basic NGRX store. The goal is to have a value in my Store (specifically called chipSelected: string), display that value in AA.component.ts, and be able to change it in BB.component.ts using a button click. In esse ...

Count the number of checkboxes in a div

In my current project, I am working on incorporating three div elements with multiple checkboxes in each one. Successfully, I have managed to implement a counter that tracks the number of checkboxes selected within individual divs. However, I now aspire to ...

Is it possible to create my TypeORM entities in TypeScript even though my application is written in JavaScript?

While I find it easier to write typeorm entities in TypeScript format, my entire application is written in JavaScript. Even though both languages compile the same way, I'm wondering if this mixed approach could potentially lead to any issues. Thank yo ...

invoking a function in one component from another component within an Angular 4 project using ng-smarttable

Utilizing ng-smarttable to display data in a table and have successfully added a custom button in a separate component. However, I am encountering an issue where the data does not reload when clicking on the button. An error message is appearing: ERROR Ty ...

Enhance the appearance of the table footer by implementing pagination with Bootstrap Angular6 Datatable styling

I utilized the angular 6 datatable to paginate the data in a table format. https://www.npmjs.com/package/angular-6-datatable Everything is functioning properly, but I am struggling with styling the footer of mfBootstrapPaginator. https://i.sstatic.net/i ...

Adding an element to an array does not automatically reflect on the user interface

After fetching JSON data from the endpoint, I am attempting to update an array but not seeing the expected results on the frontend. export class LocationSectionComponent implements OnInit{ myControl = new FormControl(); options : string[] = [' ...

Ways to modify Angular pipe without specifying data types

I am in the process of extracting an Angular pipe from an application to a library. The current pipe is tied to specific types, but I want to change it to use generic types while maintaining type safety. Original Pipe: import { Pipe, PipeTransform } fr ...

Utilizing BehaviourSubject for cross-component communication in Angular

My table is populated with data from a nodeJS API connected to methods inside my service. I attempted using a Behavior Subject in my service, initialized as undefined due to the backend data retrieval: Service: import { Injectable } from "@angular/core" ...

Leveraging environment variables in NextJS - passing values to the client side

I'm facing a frustrating issue with my project in server mode. We need to pass environment variables at runtime and access them on both the server and client side. Following the publicRuntimeConfig method from the documentation, everything works fine ...

Utilize the ref attribute when working with Material UI InputLabel components

Is there a way to access the ref parameter of an InputLabel from the @material-ui/core library using TypeScript? When I attempt to do so, the following code produces an error related to ref: TS2769: No overload matches this call. export class ComboBo ...