storybook icon indicating copy to clipboard operation
storybook copied to clipboard

Wrong rendering of Angular component (*ngIf)

Open khan990 opened this issue 4 years ago • 3 comments

Describe the bug A simple component with an *ngIf has unexpected behaviour. You can reproduce the issue from this project.

Lets say I create a wrapper over ionic button component.

<ion-button
    [fill]="buttonStyle"
    [expand]="expand"
    [disabled]="disabled"
    (click)="onClick($event)"
>
    <ng-container *ngIf="isLoading === false; else loadingSpinner">
        {{ buttonText }}
    </ng-container>
    <ng-template #loadingSpinner>
        <ion-spinner name="crescent"></ion-spinner>
    </ng-template>
</ion-button>
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';

@Component({
  selector: 'app-button',
  templateUrl: './button.component.html',
  styleUrls: ['./button.component.scss']
})
export class ButtonComponent {

  @Input() buttonText: string;
  @Input() buttonStyle:
        | 'clear'
        | 'outline'
        | 'solid'
        | 'default'
        | undefined = 'solid';
  @Input() disabled = false;
  @Input() expand: 'full' | undefined = undefined;
  @Input() isLoading = false;
  @Output() clickEvent: EventEmitter<MouseEvent> = new EventEmitter<
      MouseEvent
  >();

  constructor() {}

  onClick(event: MouseEvent): void {
    this.clickEvent.emit(event);
  }

}
import { Meta, Story } from '@storybook/angular';
import { action } from '@storybook/addon-actions';
import { ButtonComponent } from './button.component';

export default {
    title: 'ion-button-wrapper',
    component: ButtonComponent,
    argTypes: {
        buttonStyle: {
            control: {
                type: 'select',
                options: ['clear', 'outline', 'solid', 'default', undefined],
            },
        },
        expand: {
            control: {
                type: 'select',
                options: ['full', undefined],
            },
        },
        isLoading: {
          control: {
            type: 'boolean'
          }
        }
    },
} as Meta;

const Template: Story = (args: ButtonComponent) => ({
    props: { ...args },
    component: ButtonComponent,
});

export const Basic: Story = Template.bind({});
Basic.storyName = 'Basic';
Basic.args = {
    buttonText: 'Button Text',
    clickEvent: (event) => {
        action('Button Click Event')(event);
    },
};

The issue is with isLoading control. The component should display one spinner, but instead, it shows two for some reason.

To Reproduce Playaround with isLoading control of ion-button-wrapper of this project

Expected behavior There should be a single spinner spinning in the button.

Screenshots image

image

khan990 avatar Nov 19 '20 20:11 khan990

Automention: Hey @MaximSagan @kroeder, you've been tagged! Can you give a hand here?

github-actions[bot] avatar Nov 20 '20 08:11 github-actions[bot]

Should be fixed by #12382. I patched my node_modules to set the props in NgZone, similar to how I did in that PR and couldn't reproduce the issue any more.

I couldn't reproduce it in chrome. Your second screenshot looks like you are using Firefox, so I tried it and was able to reproduce the issue.

The ion-spinner implementation is doing a few unique things with how they write components, so I didn't try to track down what exactly is causing the problem. My assumption is that they are registering some events that rely on NgZone to trigger change detection. Maybe Chrome is completing the event before the current change detection tick completes and Firefox is completing it after the current tick. It is only a guess though. Currently inputs changed by a control are not set inside NgZone, so an events registered as a result would also not be hooked by NgZone, unless it is manually entered.

Marklb avatar Nov 20 '20 19:11 Marklb

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

stale[bot] avatar Dec 25 '20 18:12 stale[bot]