Material dialog pops up blank before showing letters on it

114 Views Asked by At

I am using angular 9.1.13 with material 9.2.4 in my electron application. I have noticed the following strange behaviour concerning the Material Dialog component.

When I try to pop up a simple dialog with only text, the dialog pops up empty in the first place, and after some milliseconds (usually 300-1000) the letters are shown up. Screenshots shown below:

When i open the dialog

enter image description here

After some milliseconds

enter image description here

The implementation of the pop up is the following:

MyDialogComponent

export class MyDialogComponent {
public infoMessage: string;

constructor(
    @Inject(MAT_DIALOG_DATA) private data: any,
    private dialogRef: MatDialogRef<MyDialogComponent>
) {
    if (data) {
        this.infoMessage = data.message;
    }
}

public static getConfig(): any {
    return {
        width: '500px',
        height: 'auto',
        disableClose: true,
        panelClass: 'dialog-info',
        backdropClass: 'dialog-info-bg'
    };
}
}

I am popping up the dialog as shown below:

const config = MyDialogComponent.getConfig();
config.data = {message: 'My text that comes later than pop up'};
this._dialogService.open(MyDialogComponent, config);

where _dialogService is the MatDialog

private _dialogService: MatDialog

Html code of MyDialogComponent

<div class="modal modal fade">
<div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
        <div class="modal-header">
            <h5 class="modal-title" id="message">{{ infoMessage }}</h5>
        </div>
        <div class="modal-footer">
            <button type="button" class="btn modal-btn close-btn">Close
            </button>
        </div>
    </div>
</div>

I have searched on the web about this strange behaviour but have not yet found any satisfying answer on how to deal with this issue, thanks in advance

2

There are 2 best solutions below

4
codequiet On BEST ANSWER

You may have an issue with change detection - Electron events and APIs don't trigger change detection in Angular. Try using ChangeDetectorRef or NgZone:

import { OnInit, ChangeDetectorRef } from '@angular/core';

...

export class MyDialogComponent implements OnInit {
public infoMessage: string;

constructor(
    @Inject(MAT_DIALOG_DATA) private data: any,
    private dialogRef: MatDialogRef<MyDialogComponent>,
    private cdr: ChangeDetectorRef
) { }

ngOnInit() {
    if (data) {
        this.infoMessage = data.message;
        this.cdr.detectChanges();
    }
}

or

import { NgZone } from '@angular/core';

...

export class MyDialogComponent {
public infoMessage: string;

constructor(
    @Inject(MAT_DIALOG_DATA) private data: any,
    private dialogRef: MatDialogRef<MyDialogComponent>,
    private zone: NgZone
) {
    if (data) {
        this.zone.run(() => {
            this.infoMessage = data.message;
        });
    }
}

Alternately you can make sure the command to open the dialog is properly picked up by Angular's change detection:

this.zone.run(() => {
    const config = MyDialogComponent.getConfig();
    config.data = {message: 'My text that comes later than pop up'};
    this._dialogService.open(MyDialogComponent, config);
});

If this resolves your problem, keep in mind for the rest of your app that anything coming from Electron will need the same handling in order to update the UI/rendered HTML.

0
Maxime Lyakhov On

You could try CdkDialog (since you already passing classes to change visuals) which is less resource demanding (affects rendering speed:

The config should be passed directly in a popup call. Instead of creating an instance of the popup component before getting config like you do:

const config = MyDialogComponent.getConfig(); // which is very weird

->

const config = {
    width: '500px',
    height: 'auto',
    disableClose: true,
    panelClass: 'dialog-info',
    backdropClass: 'dialog-info-bg'
};
this._dialogService.open(MyDialogComponent, config);

And data could be public without if in constructor, since you always pass it:

@Inject(MAT_DIALOG_DATA) public data: {message: string},

Template:

<h5 class="modal-title" id="message">{{ data.message }}</h5>

I've never worked with electron, so it may not be enough. You may be executing microtasks when open call happens. You have relatively old Angular version, so it might be old project too, does it have other examples of using dialog?

To measure overall latency you can use console.log(window.performance.now()) before calling open and the same in ngOnInit of the popup.