[Solved] Ember Power Select - selection not highlighted

The correct value shows in the field but when clicking the dropdown, the first item is highlighted. image

<PowerSelect
  @renderInPlace={{true}}
  @selected={{this.destination}}
  @onChange={{this.select}}
  @options={{@states}} as |state|
 >
      {{state.name}}
    </PowerSelect>


export default class PropertiesPropertyEditAddressComponent extends Component {
  @tracked destination = null;

  constructor() {
    super(...arguments);
    this.destination = this.args.property.address.state;
  }

  @action
  select(value) {
    this.destination = value;
    set(this.args.property.address, "state", value);
  }
}

@states is an array of state objects…such as { name: 'Alaska', abbreviation: 'AK' }.

I think the problem is that power select matches by option object and you’re expecting it to match by string. The options you’re passing in @states are presumably a list of objects. However when you set the destination property in the constructor you’re not setting it to one of those objects, you’re setting it to a completely different object (this.args.property.address.state). That object, even if it has the same state name, will have a different reference (it’s a different object in memory). So even though it renders the name correctly, it can’t match the destination object with the correct option from @states.

There are a number of ways to solve this. One would be you could have a computed property that gets the right state from @states for you, and returns it, based on name matching. E.g.:

  selectedState() {
    return this.args.states.findBy('name', this.destination.name);
  }

and then change the template bit to

  @selected={{this.destination}}

Unfortunately you’ve also got an issue with component state management. You shouldn’t (as a rule) mutate args like this:

    set(this.args.property.address, "state", value);

IIRC it only works because there is sort of a hole in enforcement which will hopefully someday be closed. Args are meant to be immutable, and if they need to be changed you should fire an action to the parent (and to the parent’s parent if the state isn’t owned by parent, and so on) to let the “state owner” do the mutation. This is DDAU (Data Down Actions Up).

So… what you probably want here, instead of having a locally tracked option (this.destination) as well as state from the outer context (args.property.address.state) is to fire an action and let the outer context handle the data mutation, and then pass the selected value in as an arg. Then you don’t need to track the arg in this component at all.

Thanks @dknutsen.

I updated my constructor to the following and it appears to be working now:

constructor() {
    super(...arguments);
    this.destination = this.args.states.findBy('name', this.args.property.address.state.name);
  }