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
Cannot create component without inserting into DOM without the deprecated ComponentFactory #45263
Which @angular/* package(s) are the source of the bug?
core
Is this a regression?
No
Description
Since Angular 13 ComponentFactory.create() is deprecated. It is advertised that we should instead use ViewContainerRef.createComponent(). However the behavior between those two methods are different and cannot necessarily replace each other for all use-cases.
My use-case is to create a component dynamically, not insert it into DOM, call a few custom methods on it, and then destroy the component. But ViewContainerRef.createComponent() will always insert the newly created component into DOM, wreaking havoc in my layout.
Was it intentional that a component cannot be instantiated without being inserted into DOM anymore ? Or should it be considered a regression in the feature set of the framework ?
Or is there an alternative API that would allow me to instantiate and destroy components without ever inserting them into DOM ?
Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
No response
Please provide the environment you discovered this bug in (run ng version)
And previously, components can be created outside components and directives. And, now that ComponentFactoryResolver is deprecated couldn't find any alternatives for the same.
I have a similar problem that I mentioned in this issue #44926 but nobody has been able to answer yet. I also think that both forms should be maintained. They are complementary.
Hi, just a quick update: we plan to look into replacement APIs for the described use-case. The new API should provide an ability to create a ComponentRef instance, i.e. you should be able to do something like this:
We don't have an ETA yet, but we'd make sure that it's available before we remove ComponentFactory from the public API.
Reacted by Adrien Crivelli, José Grancha Bonora, michalsisak, Jan Holas, alienwareone, Patrick Bassner, Fang Liu, Israel de la Barrera, Leon Eck, Mohammad Ali and 12 more
We've got the same problem. We need to pop a modal that shows a TemplateRef constructed by the component initialisation.
In this case the component is never added anywhere in the page, only that specific sub-view is shown.
In this case the viewRef where the template is rendered is ultimately supplied through Angular Material's MatDialog service, but this is abstracted away (as it should be).
I have another use case where I am struggling with what to replace componentFactoryResolver with. In my situation, I have a page that is fully done in angular, but the result is a mostly static page. So it is rendered with node and on the client-side, I use compileModuleAsync along with componentFactoryResolver to target the 1 or 2 sections that are the already rendered in DOM to make them controllable with angular on the client-side so that they become functional.
Imagine a page where at the bottom it has a QnA section and that section would be controllable by angular. Node renders the initial view and then in comes angular on the client-side and replaces it with the interactable version where it has things like loading more answers via ajax, having a reply form, voting, etc. This helps us a lot with web core vitals where the js size is smaller and by having only parts of the page be in angular on the client-side we avoid triggering a high LCP as the entire DOM would get replaced in case of a full-page bootstrap.
In my case, I benefited from "factory.create(injector,[],selector)" where "selector" would be the target section.
And previously, components can be created outside components and directives. And, now that ComponentFactoryResolver is deprecated couldn't find any alternatives for the same.
I have a piece of code which looks exactly like this.
I use it to append dynamic components anywhere in the dom...But now I don't know what alternative I can use...
I guess the solution could be instantiating a standalone component (bootstrapApplication, use some InjectionToken to provide the dynamic component class) where, using the viewContainerRef we could instantiate the dynamic component...
Then retrieve the HTML and move it anywhere in the DOM...
It seems a bit convoluted and I'm not sure how dependencies would be handled...
Activity
GeorgianStan commentedon Mar 19, 2022
I also face this issue and a workaround is to inject ViewContainerRef inside the service.
Like in this example
patryk-zielinski93 commentedon Mar 22, 2022
I have the same problem
JGrancha commentedon Mar 28, 2022
I have a similar problem that I mentioned in this issue #44926 but nobody has been able to answer yet. I also think that both forms should be maintained. They are complementary.
AndrewKushnir commentedon Mar 30, 2022
Hi, just a quick update: we plan to look into replacement APIs for the described use-case. The new API should provide an ability to create a
ComponentRefinstance, i.e. you should be able to do something like this:We don't have an ETA yet, but we'd make sure that it's available before we remove
ComponentFactoryfrom the public API.fhljys commentedon Apr 22, 2022
Following
Ghostbird commentedon May 12, 2022
We've got the same problem. We need to pop a modal that shows a
TemplateRefconstructed by the component initialisation.In this case the component is never added anywhere in the page, only that specific sub-view is shown.
In this case the
viewRefwhere the template is rendered is ultimately supplied through Angular Material'sMatDialogservice, but this is abstracted away (as it should be).id1945 commentedon May 29, 2022
//====================================================//
👉 https://stackblitz.com/edit/angular-lazy-loading-compiler-module-async-v13 👈
//====================================================//
LubosD commentedon May 29, 2022
@id1945 How is this relevant? You're obviously placing these components into the DOM.
Ghostbird commentedon May 29, 2022
@id1945 This issue is about the case where you cannot have a
this.containerto callcreateComponenton, for whatever reason.pitAlex commentedon Jun 14, 2022
I have another use case where I am struggling with what to replace componentFactoryResolver with. In my situation, I have a page that is fully done in angular, but the result is a mostly static page. So it is rendered with node and on the client-side, I use compileModuleAsync along with componentFactoryResolver to target the 1 or 2 sections that are the already rendered in DOM to make them controllable with angular on the client-side so that they become functional.
Imagine a page where at the bottom it has a QnA section and that section would be controllable by angular. Node renders the initial view and then in comes angular on the client-side and replaces it with the interactable version where it has things like loading more answers via ajax, having a reply form, voting, etc. This helps us a lot with web core vitals where the js size is smaller and by having only parts of the page be in angular on the client-side we avoid triggering a high LCP as the entire DOM would get replaced in case of a full-page bootstrap.
In my case, I benefited from "factory.create(injector,[],selector)" where "selector" would be the target section.
2 remaining items
tonysamperi commentedon Jul 7, 2022
I have a piece of code which looks exactly like this.
I use it to append dynamic components anywhere in the dom...But now I don't know what alternative I can use...
I guess the solution could be instantiating a standalone component (bootstrapApplication, use some InjectionToken to provide the dynamic component class) where, using the viewContainerRef we could instantiate the dynamic component...
Then retrieve the HTML and move it anywhere in the DOM...
It seems a bit convoluted and I'm not sure how dependencies would be handled...
pkozlowski-opensource commentedon Jul 8, 2022
@tonysamperi the alternative is being worked on in #46685
tonysamperi commentedon Jul 9, 2022
@pkozlowski-opensource I saw the commits, cool! Thanks for letting me know!
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.