New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ngIf cryptic error when a then block is set to a non template #16410

Closed
1heg0d opened this Issue Apr 28, 2017 · 8 comments

Comments

Projects
None yet
6 participants
@1heg0d

1heg0d commented Apr 28, 2017

Edit (vicb) - the error is caused by the ngIf

<p *ngIf="user.removed; else activeBlock">User had been removed: {{user.removed | date : 'dd.MM.yyyy'}}</p>
<p #activeBlock>User is active</p>

The second <p> should be a <ng-template> but the error message does not help

Hi.
Probably i found an error.

I've used ngIf block inside ngFor block also inside ngFor block placed another ngFor.

Like this:

<tr *ngFor="let user of users">
    <td>
        <p *ngFor="let login of users.logins">{{login}}</p>
    </td>
    <td>
        <p *ngIf="user.removed; else activeBlock">User had been removed: {{user.removed | date : 'dd.MM.yyyy'}}</p>
        <p #activeBlock>User is active</p>
    </td>
</tr>

And this throws error: templateRef.createEmbeddedView is not a function

I'm using this code now (instead previous):

<tr *ngFor="let user of users">
    <td>
        <p *ngFor="let login of users.logins">{{login}}</p>
    </td>
    <td>
        <p *ngIf="user.removed">User had been removed: {{user.removed | date : 'dd.MM.yyyy'}}</p>
        <p  *ngIf="!user.removed">User is active</p>
    </td>
</tr>

Thanks for attention.

@tamasfoldi

This comment has been minimized.

tamasfoldi commented Apr 28, 2017

Hi!

Try to put your else block into an <ng-template></ng-template> block as it shown in the changelog
Like this:

<tr *ngFor="let user of users">
    <td>
        <p *ngFor="let login of users.logins">{{login}}</p>
    </td>
    <td>
        <p *ngIf="user.removed; else activeBlock">User had been removed: {{user.removed | date : 'dd.MM.yyyy'}}</p>
        <ng-template #activeBlock>
           <p>User is active</p>
       </ng-template>
    </td>
</tr>
@1heg0d

This comment has been minimized.

1heg0d commented Apr 28, 2017

@tamasfoldi
This is not solution, unfortunately.
If i delete the nested ngFor everything is working (#activeBlock in p tag).

@vicb

This comment has been minimized.

Contributor

vicb commented Apr 28, 2017

Please add a plunker that reproduce the issue. Without further details we will close the issue. Thanks.

@1heg0d

This comment has been minimized.

1heg0d commented Apr 28, 2017

@vicb
https://embed.plnkr.co/Uvji8ookThtrjg9gflhN/

activeBlock should be ng-template?

@aravindfz

This comment has been minimized.

Contributor

aravindfz commented May 1, 2017

The problem is because you are using removed : null when {{null}} is printed in HTML it throws that error. Check this plunker

@vicb

This comment has been minimized.

Contributor

vicb commented May 1, 2017

@1heg0d exactly, then you be set to a template ref: <ng-template #activeBlock>User is active</ng-template> solves your issue.

I'll leave this open so that we improve the error message.

@vicb vicb changed the title from ngFor problem to ngIf cryptic error when a then block is set to a non template May 1, 2017

@titusfx

This comment has been minimized.

titusfx commented Jul 12, 2017

The conclusion is you CAN'T use ngIf then else without ng-template ? o.O

@chai-jay

This comment has been minimized.

chai-jay commented Sep 26, 2017

@titusfx In short, yes.

The *ngIf directive is a structural directive with the asterisk character * being a syntatic sugar, and it expects you to pass <ng-template> for the else condition's TemplateRef in the ngIf directive code to grab the referenced markup correctly. When you write <div *ngIf="showThis">Test</div>, it really becomes this:

<ng-template [ngIf]="showThis">
    <div>Test</div>
</ng-template>

And when you write this:

<div *ngIf="showThis; else thatTemplate>Test</div>
<ng-template #thatTemplate>
    <div>Else template</div>
</ng-template>

It gets desugared to something like this (I'm not 100% sure on this desugaring):

<ng-template [ngIf]="showThis" [ngIfElse]="thatTemplate">
    <div>Test</div>
</ng-template>
<ng-template #thatTemplate>
    <div>Else template</div>
</ng-template>

For more info, read these sections: https://angular.io/guide/structural-directives#what-are-structural-directives and https://angular.io/guide/structural-directives#the-asterisk--prefix.

@vicb vicb added the freq1: low label Feb 6, 2018

@ngbot ngbot bot added this to the Backlog milestone Feb 6, 2018

trotyl added a commit to trotyl/angular that referenced this issue Feb 17, 2018

trotyl added a commit to trotyl/angular that referenced this issue Feb 17, 2018

trotyl added a commit to trotyl/angular that referenced this issue Feb 17, 2018

trotyl added a commit to trotyl/angular that referenced this issue Feb 17, 2018

@vicb vicb closed this in 67cf11d Feb 18, 2018

jbogarthyde added a commit to jbogarthyde/angular that referenced this issue Feb 23, 2018

smdunn pushed a commit to smdunn/angular that referenced this issue Feb 28, 2018

leo6104 added a commit to leo6104/angular that referenced this issue Mar 25, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment