Ivy Template Compiler misinterprets someExternalServiceFunction(this) when surrounded by *ngIf
See original GitHub issue🐞 bug report
Affected Package
Ivy Template Compiler
Is this a regression?
Kindof. Not version specific, however it’s dependent on which renderer is enabled (legacy/ivy). tsconfig
"angularCompilerOptions": {
"enableIvy": true // bug
"enableIvy": false // no bug
}
Description
Using “this” variable in template to access entire Component (as opposed to single property) can be interpreted wrong if surrounded by an *ngIf. (template compiler uses wrong context variable)
🔬 Minimal Reproduction
I can’t use StackBlitz because it doesn’t allow changing tsconfig.app.json
Minimal repro at: https://github.com/speige/ivy-this-context-bug
Swap enableIvy between true/false in tsconfig.app.json to see the regression/breakingChange.
This is a blank starting project, the only relevant code is here: app.component.html
<div *ngIf="true">
<span>With NgIf, Stringify(this) => </span>
{{Stringify(this)}}
</div>
<div>
<span>Without NgIf, Stringify(this) => </span>
{{Stringify(this)}}
</div>
<br /><br />
<div *ngIf="true">
<span>With NgIf, Stringify(this.Property) => </span>
{{Stringify(this.Property)}}
</div>
<div>
<span>Without NgIf, Stringify(this.Property) => </span>
{{Stringify(this.Property)}}
</div>
app.component.ts
export class AppComponent {
public Property = { Key: 'value' };
public Stringify(object: any) : string {
return JSON.stringify(Object.getOwnPropertyNames(object));
}
}
🔥 Exception or Error
Working Screenshot (enableIvy: false)
Broken Screenshot (enableIvy: true)
When comparing the images, the addition of property “ngContext” is not a problem because it’s just ivy internals. However, the [“$implicit”, “ngIf”] is a problem because it’s the completely wrong variable. If you debug the code you’ll see it’s the context object for the surrounding *ngIf.
🌍 Your Environment
Angular Version:
Angular CLI: 8.0.0-rc.4
Node: 10.15.0
OS: win32 x64
Angular: 8.0.0-rc.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.800.0-rc.4
@angular-devkit/build-angular 0.800.0-rc.4
@angular-devkit/build-optimizer 0.800.0-rc.4
@angular-devkit/build-webpack 0.800.0-rc.4
@angular-devkit/core 8.0.0-rc.4
@angular-devkit/schematics 8.0.0-rc.4
@ngtools/webpack 8.0.0-rc.4
@schematics/angular 8.0.0-rc.4
@schematics/update 0.800.0-rc.4
rxjs 6.4.0
typescript 3.4.5
webpack 4.30.0
Anything else relevant? This is probably an extremely rare use case & is possibly a code smell. However, my code was using it. It was easy to find a temporary workaround once the root cause was diagnosed.
My use case was I had a shared service with utility functions that needed an instance of a Component to work on. Similar to a BaseComponent or RootScope. The passed in reference was a weird context object instead of a Component. Was working before the ivy upgrade.
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (4 by maintainers)
I would say that now it points to the exactly value it should be pointed before.
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.