3

I am currently writing an LWC OSS project and am currently confused about some reproducible side-effects on a <select>. The element can be "injected" from outside, by setting the value of said element using javascript. I created this playground so you can experience it yourself: Playground

The javascript loggs everything as expected. But the <select> itself does not reflect the value, instead, it jumps to the first value very often. I don't see any reason why this happens, at all.

html:

<template>
    <button onclick={prev}>prev</button>

    <select onchange={select}>
            <option for:each={options} 
                    for:item="option" 
                    key={option.value} 
                    value={option.value}
                    selected={option.selected}>
                {option.value}
            </option>
    </select>

    <button onclick={next}>next</button>
</template>

js:

import { LightningElement } from "lwc";

export default class App extends LightningElement {
    selected = 'a';
    values = ['a', 'b', 'c', 'd', 'e'];
    
    get options() {
        const selected = this.selected;
        return this.values.map((option) =>
            ({
                value: option,
                get selected() {return this.value === selected}
            }));
    }
    
    select(evt) {
        console.log(evt.target.value);
        this.selected = evt.target.value;
    }
    
    prev() {
        let i = this.values.indexOf(this.selected);
        console.log('current', this.selected);
        if(i > 0) {
            this.selected = this.values[--i];
            console.log('prev', this.selected);
        }
    }
    
    next() {
        let i = this.values.indexOf(this.selected);
        console.log('current', this.selected);
        if(i >= 0 && ++i < this.values.length) {
            this.selected = this.values[i];
            console.log('next', this.selected);
        }
    }
}

1 Answer 1

3

Using the selected property appears to confuse the browser. I've tried several iterations, and it seems to "randomly" confuse the values. For example, I once had it where it showed d [ a ], and looking at the browser's DOM inspector, it showed:

<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
<option value="d" selected>d</option>
<option value="e">e</option>

As a workaround, use selectedIndex to set the value:

this.template.querySelector('select').selectedIndex = index

Here's the updated code.

I'll do some more research on this, but it seems to be related to how changes are re-rendered in the DOM.

2
  • Thank you Sfdcfox for your investigations! Do you think it is related to lwcs for:each and key tracking, or is it a general html issue? I am not sure how to investigate either of both, so thanks for your effort and the nice workaround!
    – itsmebasti
    Commented Feb 12, 2022 at 22:16
  • 1
    @Basti I'm a pretty decent developer, I can do the research, it might take me a bit. If I find it's a bug in LWC, I'll file a bug for it.
    – sfdcfox
    Commented Feb 12, 2022 at 23:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .