2

What is the correct way to bind a select element to an object (rather than a string value) but still have the HTML element submit a string value?

I've managed to get this working, but it almost seems like I'm exploiting a bug:

<select v-model="selected" v-on:change="price=selected.price">
    <option v-for="item in items" v-bind:value="item" value="{{ item.id }}">{{ item.name }}</option>
</select>

This works as intended: the "selected" property is attached to the "item" object, but the form POSTs just the item's ID. However, if I reverse the order of the HTML attributes, so that value={{ item.id }} comes before v-bind:value="item", then the form POSTs "[Object]" rather than, e.g., "3".

The fact that it's so fragile makes me think I'm doing something wrong.

So what's the right way to handle this?

AdamTheHutt
  • 8,287
  • 8
  • 33
  • 33

3 Answers3

1

I had a similar situation in which I built several vue components that could be used both within a vue component or within a standard form.

<select v-model="selected" v-on:change="price=selected.price">
    <option v-for="item in items" :value="JSON.stringify(item)">{{ item.name }}</option>
</select>

Appears to be what you are after. I also had success using a computed property or filter but I decided that stringify was most readable.

twikken
  • 35
  • 5
1

I fixed it by using this approach:

<select v-model="product">
  <option v-for="obj in choices" :value="obj">{{ obj.name }}</option>
</select>
<input type="hidden" name="product" :value="choice.id">

In summary: don't give your select a name but give that name to your hidden input and provide the ID as value on that element instead.

sparkle
  • 1,024
  • 1
  • 8
  • 12
0

I see in both the cases, HTML being rendered as following:

<select>
  <option value="[object Object]">name1</option>
  <option value="[object Object]">name2</option>
  <option value="[object Object]">name3</option>
  <option value="[object Object]">name4</option>
</select>

Case 1 : v-bind:value="item" value="{{ item.id }}" : fiddle

Case 2 : value="{{ item.id }}" v-bind:value="item" : fiddle

So both the cases are equivalent as far as HTML being rendered. Ideal way to do it without confusion will be just using v-bind:value="item" like following:

<select v-model="selected" v-on:change="price=selected.price">
    <option v-for="item in items" v-bind:value="item">{{ item.name }}</option>
</select>

You should v-bind to item or item.id depending on what you want to assign to selected variable.

Saurabh
  • 71,488
  • 40
  • 181
  • 244
  • Thanks, but neither of those works. If I `v-bind` to `item` then the value submitted by the form is the string "[object Object]". If I `v-bind` to `item.id`, then that problem is fixed, but the `selected` model is just the id, not the whole item, which I need it to be. – AdamTheHutt Dec 25 '16 at 00:36
  • Why do you want to have `selected ` to be whole model: `selected ` will be whatever you use `v-bind` in ` – Saurabh Dec 25 '16 at 06:17
  • I need selected to be the whole model because I need to reference the "price" property of the model (item.price). In the fiddle you posted, that works (more or less) but then we're back to the original problem. When that form is posted, the value of that select field will be "[object Object]". I need it to be the item.id. – AdamTheHutt Dec 27 '16 at 16:38
  • @adamthehutt check this fiddle: http://jsfiddle.net/sh9kd1gg/3/, If this not works, Can you update this fiddle with your issue. – Saurabh Dec 27 '16 at 17:10
  • Yes, that works, but it requires that you intercept the form submission in javascript (to capture selected.id and overwrite the value of that form field). I was hoping to be able to do a normal HTML form submission. But I guess that's not possible. Thanks anyway for your help. – AdamTheHutt Dec 28 '16 at 17:20
  • @adamthehutt can you update the fidlle the way you are doing it, will have a look. – Saurabh Dec 28 '16 at 17:25
  • @adamthehutt When in JS you directly print a Object it shows "Object Object" only, see [this](http://stackoverflow.com/questions/5612787/converting-an-object-to-a-string) and [this](http://stackoverflow.com/questions/16493498/json-stringify-returns-object-object-instead-of-the-contents-of-the-object). I have modified your same fiddle in two ways [here](http://jsfiddle.net/sh9kd1gg/9/) and [here](http://jsfiddle.net/sh9kd1gg/10/), hope this helps. – Saurabh Dec 30 '16 at 17:03
  • I appreciate your help. Perhaps I'm not being clear. I understand how the javascript works. I'm interested in the data that the form POSTs to the server. That is "[object Object]", which is not useful for the server-side processing code. The server needs to receive an ID. – AdamTheHutt Jan 01 '17 at 06:34