Skip to content

MdSelect hangs browser if FormControl does not exist #2716

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

Closed
mrlund opened this issue Jan 19, 2017 · 14 comments
Closed

MdSelect hangs browser if FormControl does not exist #2716

mrlund opened this issue Jan 19, 2017 · 14 comments
Labels
cannot reproduce The team is unable to reproduce this issue with the information provided

Comments

@mrlund
Copy link

mrlund commented Jan 19, 2017

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);
    };
@kara
Copy link
Contributor

kara commented Jan 19, 2017

@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?

@kara kara added the cannot reproduce The team is unable to reproduce this issue with the information provided label Jan 19, 2017
@xban1x
Copy link

xban1x commented Jan 20, 2017

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

@mrlund
Copy link
Author

mrlund commented Jan 21, 2017

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

@mrlund
Copy link
Author

mrlund commented Jan 22, 2017

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.

@mrlund mrlund closed this as completed Jan 22, 2017
@aufdenpunkt
Copy link

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

@kara
Copy link
Contributor

kara commented Jan 25, 2017

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

@mrlund
Copy link
Author

mrlund commented Jan 26, 2017

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?

@mrlund
Copy link
Author

mrlund commented Jan 30, 2017

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.

@mrlund
Copy link
Author

mrlund commented Jan 31, 2017

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>

@mrlund mrlund reopened this Jan 31, 2017
@mrlund
Copy link
Author

mrlund commented Feb 1, 2017

@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).

@emin93
Copy link

emin93 commented Feb 6, 2017

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.

@mrlund
Copy link
Author

mrlund commented Feb 7, 2017

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

@kara
Copy link
Contributor

kara commented Feb 10, 2017

Should have been closed by #2955

@kara kara closed this as completed Feb 10, 2017
@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 Sep 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cannot reproduce The team is unable to reproduce this issue with the information provided
Projects
None yet
Development

No branches or pull requests

5 participants