Components: MdSelect hangs browser if FormControl does not exist

Created on 19 Jan 2017  路  14Comments  路  Source: angular/components

Bug, feature request, or proposal:

Bug

What is the expected behavior?

No values populated in the select control, or exception thrown

What is the current behavior?

Hangs the browser (Chrome and Safari at least, Edge/FF not tested)

What are the steps to reproduce?

set formControlName to the name of a control that doesn't exist on the formGroup, i.e. if you accidentally left out a form control. If you're using form.patchValue() to set the form controls it seems to prevent this issue if the control name is in the object passed to patchValue(), which might make the bug appear more random.

i.e.

        <md-select placeholder="Country" formControlName="Country">
            <md-option *ngFor="let country of countries" [value]="country.IsoCode">
                {{country.Name}}
            </md-option>
        </md-select>

where "Country" is not the name of a FormControl on the current FormGroup.

Providing a Plunker (or similar) is the best way to get the team to see your issue.
Plunker template: http://plnkr.co/edit/o077B6uEiiIgkC0S06dd

What is the use-case or motivation for changing an existing behavior?

Which versions of Angular, Material, OS, browsers are affected?

Is there anything else we should know?

Seems to be an infinite loop running here:

    /**
     * Sets the select's value. Part of the ControlValueAccessor interface
     * required to integrate with Angular's core forms API.
     *
     * @param value New value to be written to the model.
     */
    MdSelect.prototype.writeValue = function (value) {
        var _this = this;
        if (!this.options) {
            // In reactive forms, writeValue() will be called synchronously before
            // the select's child options have been created. It's necessary to call
            // writeValue() again after the options have been created to ensure any
            // initial view value is set.
            Promise.resolve(null).then(function () { return _this.writeValue(value); });
            return;
        }
        this._setSelectionByValue(value);
    };
cannot reproduce

Most helpful comment

Hi guys,

I got a similar issue when I try to render multiple md-options with an array of objects. The browser hangs when angular is trying to render the view.

This doesn't work:
screen shot 2017-01-25 at 23 50 23
screen shot 2017-01-25 at 23 50 49

But this does:
screen shot 2017-01-25 at 23 52 13

Any ideas?

Thanks

All 14 comments

@mrlund I'm having trouble replicating this. When I try to create a repro case given the code above, I get the expected error: "Cannot find control with name 'Country'".
http://plnkr.co/edit/e5Scd1wzh6KA2fdBew8E?p=preview

Can you provide a plunker repro case?

Use md-select without forms. You will see the issue @kara.

@kara @xban1x My md-select is within a form, like
<form novalidate [formGroup]="form">
...if that's what you mean?

My project is not ideally suited to copy to a plunker, but I'll try to investigate a little further and see if I can come up with additional info, or at least move enough to repro.

Hmmm.... There's definitely an issue there somewhere, as I've hit this before, but it doesn't seem to be where I thought it was, and I'm also unable to reproduce in my original project now.

I'll keep an eye out for it in the future. Closing for now.

Hi guys,

I got a similar issue when I try to render multiple md-options with an array of objects. The browser hangs when angular is trying to render the view.

This doesn't work:
screen shot 2017-01-25 at 23 50 23
screen shot 2017-01-25 at 23 50 49

But this does:
screen shot 2017-01-25 at 23 52 13

Any ideas?

Thanks

@aufdenpunkt Can you create a plunker repro case for us?

Could this be related to the rendering of options somehow?

By attaching the VS Code debugger and manually breaking, and then stepping through a couple of times, I was able to determine the browser was hanging because of an infinite loop, repeatedly hitting and satisfying the if (!this.options) condition quoted above, which just seems to call writeValue recursively until there's options?

I'm hitting this issue again, but at least narrowing in on the cause.

It's consistently happening when a specific set of data is loaded, i.e. load one set of data, no problem, load another set of data and it hangs on the writeValue loop, waiting for the options to load. The strange thing is that the arrays used in the options *ngFor are hard coded in both cases, and set in the constructor.

I've compared the JSON of the two data sets, and found no real difference between them. They seem to contain the same properties and similar values, yet loading one causes the infinite loop, while the other doesn't.

Any ideas for things to check out would be welcome.

I figured it out for this case, and it turns out the issue might be that it's obscuring errors happening elsewhere on the page, rather than being the actual source of the bug. In my example I was using a string.split() as the source of an *ngFor elsewhere on the page, and if that would fail (like a null value instead of a string) I would get stuck in this loop with the MdSelect not populating the options and looping infinitely.

My code elsewhere on the page, completely unrelated to the MdSelect is below. I realize this is a terrible hack and that I deserve the pain caused for writing that, but the point stands that it causes the browser to freeze with no errors or any way to debug the source issue.

<span *ngFor="let tag of form.controls.SocialHandleFacebook.value.split(' ')">
       <i class="fa fa-facebook" aria-hidden="true"></i>
       {{ tag }}
</span>

@kara Here's the repro plunk: http://plnkr.co/edit/0GccFWP4wsAD9Or9jgHn?p=preview
Set the SocialHandleFacebook FormControl value to null to hit the exception that causes the MdSelect to loop. (NB: it should hang your browser).

I don't know if this issue is related with mine (#2950) but it seems to be different imho since it doesn't have anything to do with the formControl.

@emin93 I think you're right. It seems unrelated to the FormControl or NgModel, and only related to the rendering of MdSelect options, which loops infinitely when another errors occurs on the page.

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._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

3mp3ri0r picture 3mp3ri0r  路  3Comments

RoxKilly picture RoxKilly  路  3Comments

constantinlucian picture constantinlucian  路  3Comments

alanpurple picture alanpurple  路  3Comments

Miiekeee picture Miiekeee  路  3Comments