How to save select state in url with Ember.js?

158 views Asked by At

I implement content filter with ember.js and I need to save filter state in URL. How can I do this?

I reed this section http://guides.emberjs.com/v1.12.0/routing/query-params/ and try to do that code http://output.jsbin.com/cixama/4 But choice saved in URL as

http://output.jsbin.com/cixama/4#/?pull=undefined

Why undefined?

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Dynamic select on Ember.js</title>
  <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
  <script src="http://builds.emberjs.com/release/ember-template-compiler.js"></script>
  <script src="http://builds.emberjs.com/release/ember.min.js"></script>
  <script src="http://builds.emberjs.com/tags/v1.0.0-beta.18/ember-data.prod.js"></script>
</head>
<body>
  <script type="text/x-handlebars" id="index">
    <form>
      {{view "select" content=model
                      optionValuePath="content.number"
                      optionLabelPath="content.title"
                      value=pull
                      prompt="Choice option"}}
    </form>
  </script>
<script id="jsbin-javascript">
App = Ember.Application.create({});

// ROUTES
App.IndexRoute = Ember.Route.extend({
  model: function() {
    return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls');
  }
});

// CONTROLLERS
App.IndexController = Ember.Controller.extend({
  queryParams: ['pull'],
  pull: null,
});
</script>



<script id="jsbin-source-javascript" type="text/javascript">App = Ember.Application.create({});

// ROUTES
App.IndexRoute = Ember.Route.extend({
  model: function() {
    return Ember.$.getJSON('https://api.github.com/repos/emberjs/ember.js/pulls');
  }
});

// CONTROLLERS
App.IndexController = Ember.Controller.extend({
  queryParams: ['pull'],
  pull: null,
});</script></body>
</html>
1

There are 1 answers

4
Andrey Mikhaylov - lolmaus On BEST ANSWER

Your problem is that the number property of the payload is an integer, while the query param is a string.

When you select an item from the dropdown, a numeric value gets written into the pull property. But the query params mechanism replaces it with a string. The dropdown sees the value changed, looks up a new value and finds nothing. It assumes that no value was chosen and sets pull to undefined.

One solution is to use two properties: one will store the original numeric value, the other will be a getter/setter computed property that would convert between numeric and text.

<form>
  {{view "select" content=model
                  optionValuePath="content.number"
                  optionLabelPath="content.title"
                  value=currentPull
                  prompt="Choice option"}}
</form>

<p>currentPull: {{currentPull}}</p>
App.IndexController = Ember.Controller.extend({
  queryParams: ['pull'],
  pull:        Ember.computed('currentPull', {
    get: function() {
      return this.get('currentPull');
    },
    set: function(key, value) {
      this.set('currentPull', parseInt(value, 10));
      return value;
    },
  }),

  currentPull: null,
});

Demo: http://output.jsbin.com/redefi/2

But a better solution would be to introduce a model layer into your app. You'd have a pull-request entity with its attributes corresponding to properties of the payload. Then you can handle the number↔text conversion in the serializer, and your business logic will stay concise and expressive.