Ville Lehtinen
Ville Lehtinen

Reputation: 33

Ember: set attribute's value with action passed from a <select> element

I'm trying to figure out how to set a new Ember Data Record's attribute's value based on choices in a select element, using the {{action}} helper. Here's my situation, simplified:

item.js route. Creates a new record that is available in the template.

model() {
  return this.store.createRecord('item');
}

new-item.hbs template. The select-element triggers the action to set the new item's color attribute.

<select {{action 'setColor' model value="target.value" on="change"}}>
  <option value="">choose</option>
  <option value="white">white</option>
  <option value="blue">blue</option>
  <option value="red">red</option>
  <option value="yellow">yellow</option>
</select>

item.js controller.

actions: {
  setColor(item, option) {
    console.log(option);
    record.set('color', option);
    console.log(item);
  }
}

Console.log(option) returns nothing. The record.set works fine, I can hardcode the option and the console.log(item) will show that the new item object has the color attribute set.

On the other hand, if I do the action call with just

onChange={{action 'setColor' value="target.value"}} 

the color gets logged correctly from the action. But if I add "model" into that action call as before with the {{action ... on="change"}} syntax, console.log(option) returns undefined and console.log(item) returns an Event with no model object attached.

Question is: How do I pass both the target.value and the model to the setColor action?

Upvotes: 2

Views: 2098

Answers (2)

roberkules
roberkules

Reputation: 6605

I just had the same issue, but was not satisfied with the accepted answer here, since I had 2 different inputs (dropdown & text-field) that used the same action (but not same path to resolve the value), so I had to use value="..." as part of the action helper.

I found the answer in https://stackoverflow.com/a/45762071/45948

so in your case it would be:

onChange={{action (action 'setColor' model) value="target.value"}}

and then simply:

actions: {
  setColor(model, option) {
    ...
  }
}

Upvotes: 0

Ember Freak
Ember Freak

Reputation: 12872

setColor function will receive event attribute as last argument by default.

onChange={{action 'setColor' value="target.value"}} 

so value attribute will be retrieved from event. so this will work as expected. but

onChange={{action 'setColor' model value="target.value"}}

value attribute will try to get target.value from model property as we sent model as first argument, and default event argument will be passed as second argument. so combining won't work.

Solution would be

onChange={{action 'setColor' model}}

and inside actions,

actions: {
  setColor(model, event) {
    let value = event.target.value;
  }
}

Upvotes: 7

Related Questions