Search code examples
angularangular-componentsangular-ng-if

*ngIf not rendering in child component using @Import property


I have shared-components module. It is exported by the app.module then imported in the module I want to use it. In shared-components module I have a component that is supposed to render base on 3 *ngIf elements (depending on number <, > or = to 0). This component receives a number through @Import someNumber (initiated to undefined)

The component tag is included inside and *ngFor loop.

Inspecting HTML code, I can see that the component receives correct value for someNumber. And interpolated evalutions {{someNumber && (someNumber < 0)} is correctly evaluated. But no *ngIf get renderered.

(I will progressively upgrade this question with (anonymised) code that seems relevant.)

child.component.html

{{(someNumber !== undefined) && (someNumber > 0)}} <!-- Renders true or false as expected -->
{{(someNumber !== undefined) && (someNumber === 0)}}  <!-- Renders true or false as expected -->
{{(someNumber !== undefined) && (someNumber < 0)}}  <!-- Renders true or false as expected -->
    
<ng-container *ngIf="(someNumber !== undefined) && (someNumber > 0)">...</ng-container> <!-- Never renders! -->
<ng-container *ngIf="(someNumber !== undefined) && (someNumber === 0)">...</ng-container> <!-- Never renders! -->
<ng-container *ngIf="(someNumber !== undefined) && (someNumber < 0)">...</ng-container> <!-- Never renders! -->

child.component.ts

import { Component, Input, OnInit } from '@angular/core';
    
@Component({
  selector: 'child-component',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
    @Input() someNumber : number | undefined;
    
    constructor() { }

    ngOnInit(): void {
    }
}

parent.component.html

<div id="stuff" class="container">
    <div *ngIf="y.length === 0" class="loading">Data is <b>loading</b>...</div>
    
    <div *ngFor="let x of y;" class="card">
        <div class="card-body">
            <h5 class="card-title">{{ x.b  | uppercase }}</h5>
            <div class="row">
                <ng-container *ngIf="x.a">
                    <div class="col-10">
                        <ul>
                            (...)
                        </ul>
                    </div>
                    <div class="childComponent Container col-1">
                        <child-component [someNumber]="x.a.someNumber"></child-component>
                    </div>
                </ng-container>
                <ng-container *ngIf="!x.a">
                    (...)
                </ng-container>
            </div>
        </div>
    </div>
    
    <a routerLink="/" class="btn btn-primary w-25">&lt; Back</a>
    
</div>

Solution

  • CommonModule

    If you don't add CommonModule to the module owning the component:

    Interpolation will work:

    {{3 + 3}}   <!-- 6 -->
    

    But anything containing *ngFor will never render.

    <ng-container *ngFor="true">U will not see me</ng-container>  <!-- Never renders! -->
    <ng-container *ngFor="false">U will not see me</ng-container>  <!-- Never renders! -->
    <ng-container *ngFor="...">U will not see me</ng-container>  <!-- Never renders! -->