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.

Angular Input setter/getter syntax with default options

See original GitHub issue

Describe the bug

Setting a default argument for a component input that uses getter/setter syntax no longer sets the initial view correctly. The internal setter is called correctly, but the view doesn’t re-render to match the input. This is despite a changeDetectionRef markForCheck or detectChanges.

However, once the initial render is done toggling the control will render correctly.

Inputs that don’t use the getter/setter syntax update correctly and setting angularLegacyRendering: false also fixes the issue

To Reproduce Steps to reproduce the behaviour:

See MWE: https://github.com/RGunning/storybook-bug-mwe/blob/master/stories/setter-bug.component.stories.ts

Expected behaviour Default story values render correctly regardless of syntax

Screenshots

Code snippets

import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input } from '@angular/core';

@Component({
  selector: 'app-setter',
  template: `<div *ngIf="isDivShowing">This should show</div>`,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SetterComponent {
  constructor(private cdr: ChangeDetectorRef) {}

  isDivShowing = false;

  @Input() set showDiv(value: boolean) {
    this.isDivShowing = !!value;
    this.cdr.detectChanges();
  }
  get showDiv() {
    return this.isDivShowing;
  }
}
import { Meta, Story } from '@storybook/angular/types-6-0';

import { SetterComponent } from './setter-bug.component';

export default {
  title: 'Setter Bug',
  component: SetterComponent,
} as Meta;

const Template: Story<SetterComponent> = (args: SetterComponent) => ({
  moduleMetadata: {
    declarations: [SetterComponent],
  },
  template: ` <app-setter [showDiv]="showDiv"></app-setter>`,
  props: args,
});

export const ShowDiv: Story<SetterComponent> = Template.bind({});
ShowDiv.args = {
  showDiv: true,
};

System

Environment Info:

  System:
    OS: macOS 10.15.7
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
  Binaries:
    Node: 14.16.0 - ~/.nvm/versions/node/v14.16.0/bin/node
    Yarn: 1.22.5 - /usr/local/bin/yarn
    npm: 6.14.11 - ~/.nvm/versions/node/v14.16.0/bin/npm
  Browsers:
    Chrome: 89.0.4389.114
    Firefox: 87.0
    Safari: 14.0.3
  npmPackages:
    @storybook/addon-actions: ^6.2.5 => 6.2.5 
    @storybook/addon-essentials: ^6.2.5 => 6.2.5 
    @storybook/addon-links: ^6.2.5 => 6.2.5 
    @storybook/angular: ^6.2.5 => 6.2.5 

Additional Context

This also appears to be an issue when using addon-docs inlineStories. InlineStories also don’t seem to respect the angularLegacyRendering: false option and need to be disabled separately docs: { inlineStories: false }, to fix this getter/setter bug.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (8 by maintainers)

github_iconTop GitHub Comments

3reactions
ThibaudAVcommented, Apr 16, 2021

@RGunning can you try this :

Make sure that you do not directly pass all args in your story props prefer a “destructuring” to control them :

const Template: Story<SampleComp> = (args) => ({
  props: {
  input1: args.input1
  },
});
1reaction
ThibaudAVcommented, Apr 19, 2021

I had also seen this :

"docs:json": "compodoc -p ./src/app/tsconfig.app.json -e json -d . --disablePrivate --disableProtected --disableLifeCycleHooks --disableInternal",

https://discord.com/channels/486522875931656193/490770949910691862/824312399884582942

Read more comments on GitHub >

github_iconTop Results From Across the Web

Angular2 @Input to a property with get/set - Stack Overflow
How and where to do you bind to [allowDay]="....". If the field (setter) name and the property name you want to use for...
Read more >
Using Getters and Setters in TypeScript and Angular
In Angular getters and setters are often used like one of the ways to Intercept input property changes. For example, we have two...
Read more >
Component interaction - Angular
The setter of the name input property in the child NameChildComponent trims the whitespace from a name and replaces an empty value with...
Read more >
@Input Setter and Getter | Angular Tutorial - YouTube
Angular Tutorial: You can format the @ Input () data coming from parent to child component using setter and getter.
Read more >
Angular: Setters vs ngOnChanges - which one is better?
Yes. It turns out, Angular does not check the previous value by invoking the getter on the property, but stores its value in...
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