question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

lazy load from ngComponentOutlet is broken after v12

See original GitHub issue

Bug Report

Affected Package

The issue is caused by package @angular/core

Is this a regression?

Yes, the previous version in which this bug was not present was: v11

Description

We have this lazy components that loads using *ngComponentOutlet directive in v11 but after upgrade to v12, the same code didn’t worked as it displays errors like Can't bind to 'ngIf' since it isn't a known property or The pipe 'async' could not be found! etc., I think this is because of the common module isn’t get referenced.

Minimal Reproduction

I have created this stackblitz repo so just open the console and you’ll see the issues.

If you downgrade it into v11, the same code works.

// alzy-two component

@Component({
  selector: 'app-lazy-2',
  template: `
    <h4>loading lazy level 2</h4>
  `
})
export class LazyTwoComponent {}

// lazy-two module
import { LazyTwoComponent } from './lazy-two.component';

@NgModule({
  imports: [CommonModule],
  declarations: [LazyTwoComponent]
})
export class LazyTwoModule {}

// lazy one

import { LazyTwoComponent } from '../lazy2/lazy-two.component';

@Component({
  selector: 'app-lazy-1',
  template: `
    <h1 *ngIf="title">{{title}}</h1>
    <ng-template [ngIf]="lazyComp | async">
     <ng-container *ngComponentOutlet="lazyComp | async"></ng-container>
    </ng-template>
  `
})
export class LazyOneComponent implements AfterViewInit {
  title = 'hello from one'
  lazyComp: Promise<Type<LazyTwoComponent>>
  ngAfterViewInit(){
    this.lazyComp = import('../lazy2/lazy-two.component')
    .then(({LazyTwoComponent})=> LazyTwoComponent)
  }
}

// lazy-one.module

import { LazyOneComponent } from './lazy-one.component';

@NgModule({
  imports: [CommonModule],
  declarations: [LazyOneComponent]
})
export class LazOneModule {}

// app.ts

import { LazyOneComponent } from './components/lazy1/lazy-one.component';

@Component({
  selector: 'my-app',
  template`<ng-container *ngComponentOutlet="lazyComp | async"></ng-container>`
})
export class AppComponent implements AfterViewInit  {

  lazyComp: Promise<Type<LazyOneComponent>>

  ngAfterViewInit(){
    this.lazyComp = import('./components/lazy1/lazy-one.component').then(({LazyOneComponent}) => LazyOneComponent)
  }
}

// app.module

import { AppComponent } from './app.component';

@NgModule({
  imports:      [CommonModule, BrowserModule],
  declarations: [ AppComponent],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Exception or Error



NG0303: Can't bind to 'ngIf' since it isn't a known property of 'h1'.
NG0302: The pipe 'async' could not be found!.

Your Environment

Angular Version:



@angular-devkit/architect       0.1201.0
@angular-devkit/build-angular   12.1.0
@angular-devkit/core            12.1.0
@angular-devkit/schematics      12.1.0
@schematics/angular             12.1.0
rxjs                            6.6.7
typescript                      4.3.4

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:21 (13 by maintainers)

github_iconTop GitHub Comments

1reaction
mlc-mlapiscommented, Jun 28, 2021

@irowbin Sure, but the main point is that the Angular compiler must understand that such a module should be taken into account. That’s why there should be something that did it in your case, and it’s not clear what it was.

There is absolutely no need to declare the component and NgModule in the same file. As long as the NgModule class is imported somewhere, you’ll be fine.

The way it works is that the Angular compiler analyzes your NgModules and figures out what components or directives are available to the component in its module scope. Once it has this data, it adds it to the component definition.

Netanel Basal’s article uses the variant of a single file for declaring a component and its module.

1reaction
mlc-mlapiscommented, Jun 28, 2021

@irowbin The logic is the same in v11 and v12. As I know, there is no difference between both versions.

Read more comments on GitHub >

github_iconTop Results From Across the Web

NgComponentOutlet - Angular
NgComponentOutlet requires a component type, if a falsy value is set the view will clear and any existing component will be destroyed. Fine...
Read more >
Angular 4 ngComponentOutlet and lazy loading modules
Now what i would like to do is lazy loading a module containing the dynamic component. I see on Github that this feature...
Read more >
Add NgModule support to ngComponentOutlet #14043 - GitHub
The use case is if someone wants to lazy load code, and then add the lazy loaded code into the page using ngComponentOutlet...
Read more >
core.mjs:7505 ng0303: can't bind to 'ngif' - You.com - You.com
NG0303: Can't bind to 'ngIf' since it isn't a known property of '[component ... angular/angularlazy load from ngComponentOutlet is broken after v12#42683.
Read more >
How to Lazy Load a Component in Angular - Telerik
This article explains various ways of lazy loading a component in Angular, including via an import statement inside an async-await function ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found