Skip to content
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

Aync pipe + optional chaining reevalutate unrelated inputs #37591

Closed
mistic100 opened this issue Jun 15, 2020 · 4 comments
Closed

Aync pipe + optional chaining reevalutate unrelated inputs #37591

mistic100 opened this issue Jun 15, 2020 · 4 comments

Comments

@mistic100
Copy link

mistic100 commented Jun 15, 2020

🐞 bug report

Affected Package

@angular/*** 9.1.9

Is this a regression?

Probably

Description

Prerequisite :

Create a component with two @Input, one of them is a setter method (it propably does not matter but having a method helps to see the problem).
Let's call "value1" the Input using a setter method and "value2" the Input applied directly on a property.

@Component({
  selector: 'hello',
  template: `
    setValue called {{count}} times<br>
    value1 : {{value1}}<br>
    value2 : {{value2}}
  `,
})
export class HelloComponent  {

  value1: any;
  count = 0;

  @Input('value1')
  set setValue1(value: any) {
    this.value1 = value;
    this.count++;
  }

  @Input() value2: any;

}

Use it :

Use this component in a view with this configuration

  • "value1" is a direct binding to a constant
  • "value2" uses an Observable + async pipe + optional chaining
@Component({
  selector: 'my-app',
  template: `
  <hello [value1]="value1" [value2]="(value2$ | async)?.i"></hello>
  `,
})
export class AppComponent  {

  value1 = 'value 1';

  value2$ = timer(1000, 1000)
    .pipe(map(i => ({i})));

}

What happens :

Everytime "value2" changes, the setter method of "value1" is called, although the value didn't changed.
If you remove the optional chaining there is no problem.

After a long debugging session in the change detector I tracked down the problem to this line
https://github.com/angular/angular/blob/master/packages/core/src/render3/pipe.ts#L221
where "bindingToInvalidateIdx" is for some reason the index of "value1" and not "value2". Because of this when the change detector runs for "value1" the old value is "NO_CHANGE" and not the actual value, hence refreshing the input.

🔬 Minimal Reproduction

https://stackblitz.com/edit/angular-ivy-xkcbs1

In the setter of "value1" I increment a counter, this counter is increment when "value2" changes.

🌍 Your Environment

Angular Version:


    "@angular/animations": "9.1.9",
    "@angular/common": "9.1.9",
    "@angular/compiler": "9.1.9",
    "@angular/core": "9.1.9",
    "@angular/forms": "9.1.9",
    "@angular/platform-browser": "9.1.9",
    "@angular/platform-browser-dynamic": "9.1.9",
    "@angular/router": "9.1.9",
    "@angular-devkit/build-angular": "0.901.7",
    "@angular/cli": "9.1.7",
    "@angular/compiler-cli": "9.1.9",
@destus90
Copy link
Contributor

destus90 commented Jun 15, 2020

Duplicate of #37194

@pkozlowski-opensource
Copy link
Member

This one sounds very similar to #37194

@mistic100
Copy link
Author

It is, hoping for a fix in next release.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants