Two Way binding on select element issue

Hi,

I have noticed a strange behavior trying to set a two-way binding with a select element. The component:

<can-component tag="pmo-dummy">
 
  <view>
    <select {($value)}="selected">
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
      <option value="3">Option 3</option>
      <option value="4">Option 4</option>
    </select>
  </view>

  <script type="view-model">
    import DefineMap from 'can-define/map/';

    export default DefineMap.extend({
      selected: {
        value: 3
      }
    });
  </script>
</can-component>

Then i start the done-serve in develop mode, but as soon i open the app in browser it throws an error:

Potentially unhandled rejection [1] TypeError: attrValue.replace is not a function
    at HTMLSerializer.escapeAttrValue (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:26:22)
    at HTMLSerializer.attr (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:45:46)
    at HTMLSerializer.attributes (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:21:24)
    at HTMLSerializer.openTag (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:10:56)
    at HTMLSerializer.serialize (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:85:24)
    at HTMLSerializer.serialize (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:99:28)
    at HTMLSerializer.serialize (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:99:28)
    at HTMLSerializer.serialize (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:99:28)
    at HTMLSerializer.serialize (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/html-serializer.js:99:28)
    at Element.get [as innerHTML] (/home/goyo/Documents/pmo/node_modules/can-simple-dom/dist/cjs/simple-dom/document/element.js:165:57)

If i remove the binding from the select and start the server again everything works fine. Without stopping the server, if i add the binding to the select element and save the file, the live reload assigns correctly the value to the select without throwing any error, but if i stop the server and start it again, the error is throwed. It only happens with the select element, i tried with input element and it works perfectly. BUT, if i set selected to 5 or any other value not listed in the options select, the error is not throwed!

I think i has something to do with the SSR, because if i start the serve in static mode (done-serve --static) everything’s works correctly.

Im using canjs version 3.0, nodejs version 6.10.3. Im stuck with this since 2 days, any help would be really appreciated. THANKS!

@Gregorio_Godoy make sure you’re importing can-stache-converters. This project is designed to help make binding to form elements easier and should make what you are trying to do work out of the box.

@phillipskevin thanks for your help! Im newbie wirth DoneJs and im a little confuse. I created the project with the donejs generator executing: donejs add app pmo. This created a basic folder structure and the node_modules folder. But i cant see the can-stache-converters module in this folder. Should i install it with npm? Like this: npm install can-stache-converters ? How do i import it later in the AppViewModel? Require or import in the AppViewModel?

I also followed the place-my-order guide and the module can-stache-converters is not required explicit as you sugested. But the guide shows an select element whit a two way binding key.

<select {($value)}="state" {{#if states.isPending}}disabled{{/if}}>
        {{#if states.isPending}}
          <option value="">Loading...</option>
        {{else}}
          {{^if state}}
          <option value="">Choose a state</option>
          {{/if}}
          {{#each states.value}}
          <option value="{{short}}">{{name}}</option>
          {{/each}}
        {{/if}}
      </select>

https://donejs.com/place-my-order.html#write-the-template

Thanks in advence!!

You’re right. can-stache-converters is not required to make this work the way it is in place-my-order.

The reason your original example isn’t working is that you are using a numeric value in your viewModel and the select options need to be strings. You can either make this work by changing it to a string in your viewModel:

      selected: {
        value: "3"
      }

or you can use the string-to-any converter like this:

  <view>
    <can-import from="can-stache-converters" />

    <select {($value)}="string-to-any(~selected)">
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
      <option value="3">Option 3</option>
      <option value="4">Option 4</option>
    </select>
  </view>

make sure you install the package first if you want to do it this way like

npm install --save can-stache-converters

@phillipskevin THANK YOU!! i was stuck since 4 days ago with this issue. Its working perfectlly now! Thanks again!!

Awesome! You’re welcome.