You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Alternative way for depreciation of ComponentFactory in order to get componentFactory inputs #44926
Which @angular/* package(s) are the source of the bug?
core
Is this a regression?
Yes
Description
Since Angular 13 the ComponentFactory is deprecated.
Since it depreciated I need an alternative way to get the inputs property that I used to get from the instance of ComponentFactory this.componentFactory.inputs
Here is example of code where I'm using the inputs
I am going to comment on a similar example in which I have tried to find an alternative solution but have not found it. I have defined this variable that exports some components that I need to create with the @angular/elements library
And then in the app.module I have the following to define the Web Components. For that I need to get the selector and I get it with the ComponentFactoryResolver:
import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule } from '@angular/common/http';
import { ComponentFactoryResolver, Injector, NgModule, Type } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { SharedModule } from '@shared';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ErrorInterceptor, JwtInterceptor } from './core/interceptors';
import { customElementComponents } from './shared/components/custom-elements';
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json')
}
function createCustomElements(injector: Injector, factory: ComponentFactoryResolver){
customElementComponents.forEach((cmp: Type<any>) => {
const element = createCustomElement(cmp, { injector: injector })
const { selector } = factory.resolveComponentFactory(cmp);
customElements.define(selector, element);
})
}
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule,
AppRoutingModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: createTranslateLoader,
deps: [HttpClient]
}
}),
SharedModule
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule{
constructor(private injector: Injector, private factory: ComponentFactoryResolver) {
createCustomElements(injector, factory);
}
}
At the internal core level, I can't comment because I don't control it, but it would still be a good idea to leave the new way of creating components and this way of working with components. At the moment it is only deprecated but I read that in version 16 it was going to be removed...
Same problem here. Our entire application framework relies on dynamic views that are created on behalf of a (JSON) view model that can be modified by the user at runtime. This model also contains values for input properties that are set on the view component after creation. Currently, we use ComponentFactory.inputs for two reasons:
to limit the setting of values to real input properties (those decorated with @Input). (Other properties of the model are ignored.)
(less important) to be able to use the template name of an input property (instead of the javascript property name) in the json model.
Same problem here. I'm creating dynamic dashboards where all of their components are created dynamically depending on the dashboard instance type. I need to get the components' inputs and outputs to validate that I'm setting them all correctly and to bind their values.
@ofirrifo it should not block you from upgrading to Angular v14, the ComponentFactory symbol is still present there. We plan to perform further research on the APIs needed to support the described use-cases and we'll provide an update once we have additional information.
@pkozlowski-opensource since one of your latest features (#46641) it is possible to set an input value (including marking for change ...).
Wouldn't it be possible to implement some methods on ComponentRef like public hasInput(name: string): boolean
and / or public getInputs(): string[].
I think this could/would solve this issue.
And as a bonus one would not have to rely on try / catch if the input is not available.
It would be possible to check the availability upfront
@demikeComponentMirror API from #46685 gets us almost there but I agree that a boolean check on the ComponentRef would be probably more convenient. @AndrewKushnir WDYT?
@pkozlowski-opensource I agree, the ComponentMirror API should provide an ability to check if an input is present. Adding an extra hasInput function to the ComponentRef feels redundant in this case and would add some non-tree-shakable code.
Activity
JGrancha commentedon Mar 1, 2022
I am going to comment on a similar example in which I have tried to find an alternative solution but have not found it. I have defined this variable that exports some components that I need to create with the @angular/elements library
And then in the app.module I have the following to define the Web Components. For that I need to get the selector and I get it with the ComponentFactoryResolver:
At the internal core level, I can't comment because I don't control it, but it would still be a good idea to leave the new way of creating components and this way of working with components. At the moment it is only deprecated but I read that in version 16 it was going to be removed...
winterer commentedon Apr 15, 2022
Same problem here. Our entire application framework relies on dynamic views that are created on behalf of a (JSON) view model that can be modified by the user at runtime. This model also contains values for input properties that are set on the view component after creation. Currently, we use
ComponentFactory.inputsfor two reasons:@Input). (Other properties of the model are ignored.)DanielIcc commentedon May 25, 2022
I have the same problem i need the selector any alternative?
sabribv commentedon Jun 2, 2022
Same problem here. I'm creating dynamic dashboards where all of their components are created dynamically depending on the dashboard instance type. I need to get the components' inputs and outputs to validate that I'm setting them all correctly and to bind their values.
ofirrifo commentedon Jun 12, 2022
@alxhub , @AndrewKushnir is this block me from upgrade to angular 14 ?
AndrewKushnir commentedon Jun 13, 2022
@ofirrifo it should not block you from upgrading to Angular v14, the
ComponentFactorysymbol is still present there. We plan to perform further research on the APIs needed to support the described use-cases and we'll provide an update once we have additional information.style(lint): disable deprecation warnings for ComponentFactory releat…
style(lint): disable deprecation warnings for ComponentFactory releat…
2 remaining items
demike commentedon Jul 4, 2022
@pkozlowski-opensource since one of your latest features (#46641) it is possible to set an input value (including marking for change ...).
Wouldn't it be possible to implement some methods on
ComponentReflikepublic hasInput(name: string): booleanand / or
public getInputs(): string[].I think this could/would solve this issue.
And as a bonus one would not have to rely on try / catch if the input is not available.
It would be possible to check the availability upfront
pkozlowski-opensource commentedon Jul 4, 2022
@demike
ComponentMirrorAPI from #46685 gets us almost there but I agree that a boolean check on theComponentRefwould be probably more convenient. @AndrewKushnir WDYT?AndrewKushnir commentedon Jul 6, 2022
@pkozlowski-opensource I agree, the
ComponentMirrorAPI should provide an ability to check if an input is present. Adding an extrahasInputfunction to theComponentReffeels redundant in this case and would add some non-tree-shakable code.demike commentedon Jul 7, 2022
On ComponentRef the non-tree-shakable code would be like:
angular-automatic-lock-bot commentedon Aug 14, 2022
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.