Skip to content
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

On Edge/IE11 input is stamping the expression placeholder as the value #375

Closed
notwaldorf opened this issue Jun 20, 2018 · 2 comments
Closed
Assignees
Milestone

Comments

@notwaldorf
Copy link

notwaldorf commented Jun 20, 2018

In a LitElement, if you are using an <input value="${props._value}"> in your template and props._value is undefined, then Edge/IE stamp the expression placeholder instead of something good:
screen shot 2018-06-20 at 12 51 14 pm

If you set a default value for _value in the element's constructor then it's fine.

Repro: https://lit-element-example-6nhwjs.stackblitz.io
(Works fine on Chrome/FF/Safari, borked on Edge/IE11)

@bgotink
Copy link
Contributor

bgotink commented Jun 24, 2018

const tpl = document.createElement('template');
tpl.innerHTML = '<input value="foo">';
const input = document.importNode(tpl.content, true).firstElementChild;

input.removeAttribute('value');
console.log('value is now:');
console.log(JSON.stringify(input.value));

This logs the value as "" for Chrome and "foo" for Edge. This explains why you get the expected result in your example in Chrome etc, but this actually accidentally also masks a bug in lit-html:

Setting the _value to empty string in the constructor means the first render will call the value property setter on the input element. When this initial _value is undefined, this setter is not called because the _equalToPreviousValues of AttributePart returns true.
This is wrong, on a first render _equalToPreviousValues should never be true.

Repro in @notwaldorf's example: https://stackblitz.com/edit/lit-element-example-sqqeig. Note how the setter never gets called unless you uncomment the this._value = ''; in the constructor.

Another result of the fact that _equalToPreviousValues returns true if the initial value is undefined is the following unexpected behaviour:

import {render, html} from 'lit-html';

render(html`
  <div test="${undefined} is ${undefined}"></div>
`, document.body);

console.log(document.body.innerHTML);

logs

<div></div>

Repro: https://stackblitz.com/edit/lit-element-example-fqhsbb

bgotink added a commit to bgotink/lit that referenced this issue Jun 24, 2018
For initial renders, _equalToPreviousValues must always return false. The other checks
will return true if all values in the part are undefined, meaning attributes can get
lost.

See lit#375
justinfagnani pushed a commit that referenced this issue Jun 25, 2018
Make `AttributePart#_equalToPreviousValues` always return false in the initial render

For initial renders, _equalToPreviousValues must always return false. The other checks
will return true if all values in the part are undefined, meaning attributes can get
lost.

See #375
@justinfagnani justinfagnani added this to the 1.0.0 milestone Aug 8, 2018
@justinfagnani justinfagnani self-assigned this Aug 21, 2018
@justinfagnani
Copy link
Collaborator

I couldn't repro this anymore, so I think it was fixed by #377, but I added a test in #448

neuronetio pushed a commit to neuronetio/lit-html that referenced this issue Dec 2, 2019
Make `AttributePart#_equalToPreviousValues` always return false in the initial render

For initial renders, _equalToPreviousValues must always return false. The other checks
will return true if all values in the part are undefined, meaning attributes can get
lost.

See lit#375
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants