Cannot insert multiple Dynamic Components in one ViewContainerRef
See original GitHub issueI’m submitting a…
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
When calling ViewContainerRef.insert(viewRef: ViewRef) multiple times to add multiple dynamic components only the last dynamic component will be attached to the dom.
Expected behavior
Multiple dynamic components are attached to the dom.
Minimal reproduction of the problem with instructions
export class DynamicComponent {
currentComponent;
@ViewChild('dynamicComponentContainer', {
read: ViewContainerRef
}) dynamicComponentContainer: ViewContainerRef;
@Input() set componentData(data: {
component: any,
inputs: any
}) {
if (!data) {
return;
}
let inputProviders = Object.keys(data.inputs).map((inputName) => {
return {
provide: inputName,
useValue: data.inputs[inputName]
};
});
let resolvedInputs = ReflectiveInjector.resolve(inputProviders);
let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.dynamicComponentContainer.parentInjector);
let factory = this.resolver.resolveComponentFactory(data.component);
let component = factory.create(injector);
// Insert the component into the dom container
this.dynamicComponentContainer.insert(component.hostView);
this.currentComponent = component;
}
constructor(private resolver: ComponentFactoryResolver) { }
}
When called from AppComponent
createComponent<T>(component: T) {
this.componentData = {
component: component,
inputs: {
input: 1
}
}
}
createComponents() {
this.createComponent(OneComponent);
this.createComponent(TwoComponent);
// There are more components to add
}
ngAfterViewInit() {
this.createComponents();
}
Workaround
Set immediate timeout solves the issue, but it is very dirty
createComponent<T>(component: T) {
setTimeout(() => {
this.componentData = {
component: component,
inputs: {
input: 1
}
}
}, 0);
I didn’t understand yet why the workaround is even working, maybe has something to do with change detection.
Please let me know if this is easily reproducible otherwise I can add a stackblitz.
What is the motivation / use case for changing the behavior?
With the current behavior it is impossible to attach multiple dynamic components to the dom and the workaround is dirty.
Environment
Angular version: 5.0.0, 5.2.0 and 5.2.3
Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 9.4.0
- Platform: Windows
Others:
Cheers, Mo
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:12 (2 by maintainers)
Top Results From Across the Web
Create multiple different dynamic components using ngFor ...
I would like to insert a dynamic list of ...
Read more >Angular dynamic component — mount once, insert on demand
I created a simple demo to test if during navigation between two routes the component would be created only once and properly reused...
Read more >Here is what you need to know about dynamic components in ...
We start with the comparison of dynamic components functionality in Angular ... a component instance from it and insert into a DOM using...
Read more >How to use ViewContainerRef with dynamic components from ...
The error happens on the last line, when trying to run the `ViewContainerRef.insert`. Error: ERROR TypeError: Cannot read property '1' of ...
Read more >Dynamic Components - Angular - w3resource
Dynamic Components in any framework/library makes building large-scale apps way easier. Angular enables dynamic component loading.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Hi @Yerkon, Indeed this is similar 👍 Thanks. In my case I am using
@ViewChild
with myViewContainerRef
to insert all of the dynamic children.@jburtondev glad it helped, Another solution would be to call
detectChanges
onchangeDetectorRef