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.

[ivy rc4] new unbound (static) input handling breaks existing code and makes component lifecycle inconsistent

See original GitHub issue

🐞 bug report

Affected Package

Is this a regression?

No.

Description

In the ivy compatibility docs you can find this important sentence about a change coming with v9/ivy:

Unbound inputs for directives (e.g. name in <my-comp name="">) are now set upon creation of the view, before change detection runs (previously, all inputs were set during change detection).

We ran into a lot of issues with this, e.g. when you use a ViewChild query in an input setter. I created a really simple example showing the problem and that the same code works for v8 but not in v9 (couldn’t reproduce it in stackblitz) https://github.com/Phil147/unbound-input-problem-v8 https://github.com/Phil147/unbound-input-problem-v9

The example is very simplified and not best practice but imagine you want to call a function of another custom component you query here. In the v9 repo you will get an error once you start the app with ng serve because the ViewChild query is not yet resolved and thus undefined.

With v8 this works fine because the inputs are set during first change detection and the ViewChild query was resolved (with static: true). With v9 this code breaks but only in the particular situation when the input is not used with a binding but with a static value. We only found this issue by accident because in our unit tests we typically used bindings, but one specific example in our documentation (of our component library) failed during runtime. This is a very confusing behavior now that the timing changes depending on how the inputs are used in templates. For me it would make more sense to keep this consistent.

From what I found this change was made to get better performance because static inputs don’t change and you can leave them out during change detection, which makes total sense. I wonder if it might be possible to still use the information you gather about static attributes but run them together with all other inputs during the first change detection run and then ignore them instead of moving their calls before the change detection happens.

🔬 Minimal Reproduction

works fine: https://github.com/Phil147/unbound-input-problem-v8 same code breaks in v9: https://github.com/Phil147/unbound-input-problem-v9

🌍 Your Environment

Angular Version:

9.0.0-rc.4
Angular CLI: 9.0.0-rc.4
Node: 12.13.0
OS: darwin x64

Angular: 9.0.0-rc.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.0-rc.4
@angular-devkit/build-angular     0.900.0-rc.4
@angular-devkit/build-optimizer   0.900.0-rc.4
@angular-devkit/build-webpack     0.900.0-rc.4
@angular-devkit/core              9.0.0-rc.4
@angular-devkit/schematics        9.0.0-rc.4
@ngtools/webpack                  9.0.0-rc.4
@schematics/angular               9.0.0-rc.4
@schematics/update                0.900.0-rc.4
rxjs                              6.5.3
typescript                        3.6.4
webpack                           4.41.2

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:16
  • Comments:10 (7 by maintainers)

github_iconTop GitHub Comments

5reactions
pkozlowski-opensourcecommented, May 27, 2020

Confirming that this is a breaking change in ivy: the timing of static inputs assignment changed and now it is happening much earlier (as compared to VE). This creates all sorts of problems in practice, but the one that comes up quite often is the assumption of static queries presence when an input setter is invoked: https://stackblitz.com/edit/angular-czurvn?file=src/app/app.module.ts

I think that the worst here is lack of predictability - a given setter will “work” or not depending on how input is provided (static vs. dynamic). I think that we should be more predictable here and set static inputs on the first update pass.

Marking it as regression. It is not a 5-minutes fix but we should be able to restore compatibility with VE. For now there is a relatively easy work-around - move to the logic to the ngOnChanges.

2reactions
shlomiassafcommented, Jun 28, 2020

@pkozlowski-opensource Any update on this?

It’s a real deal for us, we have a large project and we use get/set descriptors a lot.

The main problem for us is the lack of predictability, sometimes it works some times it does not.

While moving to ngOnChanges looks like a quick fix, it is not (for us). It might be for 1 or 2 components but on scale it becomes hard because you also move logic here, it’s not a simple code transformation… state is involved.

The other quick fix we have is to ignore all static bindings to angular inputs. We will force binding and loose the extra perf of one-time binding of static values.

<my-cmp [myInput]="'myString'"></my-cmp>

Can this be in the next v10.x minor/patch?

I understand you might have greater priorities but you stated it should be an easy fix and frankly this un-deterministic behavior is (IMHO) a major issue for a framework.

Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

React lifecycle methods: An approachable tutorial with examples
Learn all about React lifecycle methods for mounting, updating, unmounting, and error handling, including new methods as of React 17.
Read more >
8.7 Release Notes Red Hat Enterprise Linux 8
The Release Notes provide high-level coverage of the improvements and additions that have been implemented in Red Hat Enterprise Linux 8.7 and document ......
Read more >
Untitled
Details on how to use ULN or http://public-yum.oracle.com to apply this update are available at http://linux.oracle.com/applying_updates.html.
Read more >
changelog « debian - linux - debian-backports: linux - Progress Linux
MX6 - mtd: Fixed breaking list in __mtd_del_partition. - [x86] gpu: Reserve stolen memory for first integrated Intel GPU - rtc: cmos: take...
Read more >
linux-next: Tree for Dec 7 - kernel
You should use "git fetch" and checkout or reset to the new master. ... Linux 6.1-rc8) Merging input-current/for-linus (8c9a59939deb Input: raydium_ts_i2c ...
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