Overview
I'm using ember-power-select in a Ember.js 3.8 project - and it half works and half doesn't !
To make the question more readable I've put all the code at the bottom of the question.
Situation
The select is configured to fetch data from an API endpoint and provide the user with a set of possible options to select from.
The route (routes/guest/new-using-ember-power-select.js) involved does a createRecord
of the model (models/guest.js) and then, ideally, changes made to both of the form elements (templates/guests/new-using-ember-power-select.js and templates/components/guest-form-ember-power-select.hbs) are reflected back into that record in the data store.
Issue
This works fine for the text input but I can't make it work for the ember-power-select.
In the current configuration (shown below) the user may :
- search for options to select;
- select an option and;
- have that selection reflected back into the
guest
instance in the data store. However the choice made is not reflected in the user interface - there appears to have been no selection made.
I would really appreciate someone pointing out what I'm doing wrong here. I feel like it might be quite a small thing but it did occur to me that I have to manage the state of the select via properties in the component and only when the form is submitted update the underlying data-store .... I would prefer not to do that but I would be interested to know if that was thought to be the best idea.
Thanks
EDIT 1: I forgot to say that I have attempted to alter the onchange
property of the ember-power-select so that instead of looking like this
onchange=(action "nationalityChangeAction")
... it looks like this ...
onchange=(action (mut item.nationality))
That has the effect that :
- the value selected is visible in the form (as you would normally expect but unlike my current effort) but
- the value placed into the underlying data store record is not a two character country code but instead an instance of the array returned the API call, an object with two properties
{"name":"New Zealand","alpha2Code":"NZ"}
.
Model
//app/models/guest.js
import DS from 'ember-data';
import { validator, buildValidations } from 'ember-cp-validations';
const Validations = buildValidations({
name: [
validator('presence', true),
],
nationality: [
validator('presence', true),
],
});
export default DS.Model.extend( Validations, {
name: DS.attr('string'),
nationality: DS.attr('string')
});
Route
//app/routes/guest/new-using-ember-power-select.js
import Route from '@ember/routing/route';
export default Route.extend({
model() {
return this.store.createRecord('guest', {
name: "",
nationality: ""
});
},
actions: {
updateNationality(slctnValue) {
this.controller.model.set('nationality' , slctnValue);
},
}
});
Template
//app/templates/guests/new-using-ember-power-select.js
<h2>Guest: Add New</h2>
<div class="well well-sm">
Demonstration of 'ember-power-select'
</div>
{{guest-form-ember-power-select
item=model
changeNationalityHandler="updateNationality"
updateRecordHandler="updateRecord"
cancelHandler="cancelAndExit"
}}
{{outlet}}
Component Template
//app/templates/components/guest-form-ember-power-select.hbs
<div class="form-vertical">
{{!-- Guest Name --}}
<div class="form-group">
<label class="control-label">Name</label>
<div class="">
{{ input type="text"
value=item.name
class="form-control"
placeholder="The name of the Guest"
focus-out=(action (mut this.errMsgDspCntrl.nameError) true)
}}
</div>
{{#if this.errMsgDspCntrl.nameError}}
<div class="text-danger">
{{v-get item 'name' 'message'}}
</div>
{{/if}}
</div>
<div class="form-group">
<label class="control-label">Countries (using power-select)</label>
<div class="">
{{#power-select
searchPlaceholder="Text to provide user info about what they can search on"
search=(action "searchCountries")
selected=item.nationality
onchange=(action (mut item.nationality))
as |countries|
}}
{{countries.name}}
{{/power-select}}
</div>
{{#if this.errMsgDspCntrl.nationalityError}}
<div class="text-danger">
{{v-get item 'nationality' 'message'}}
</div>
{{/if}}
</div>
{{!-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--}}
{{!-- Buttons --}}
<div class="form-group">
<div class="">
<button type="submit" class="btn btn-default" {{action "buttonSaveClicked" item}}>{{buttonLabel}}</button>
<button type="button" class="btn btn-default" {{action "buttonCancelClicked" item}} >Cancel</button>
</div>
</div>
</div>
{{yield}}
Component
//app/components/guest-form-ember-power-select.js
import Component from '@ember/component';
export default Component.extend({
actions:{
searchCountries(term) {
//Response to :
//
//https://restcountries.eu/rest/v2/name/z?fields=name;alpha2Code
//
//
//looks like this
// [
// ...
// {"name":"New Zealand","alpha2Code":"NZ"}
// ...
// ]
//
let url = `https://restcountries.eu/rest/v2/name/${term}?fields=name;alpha2Code`
let dbg = fetch(url)
.then(function(response) {
return response.json();
});
return dbg;
},
nationalityChangeAction(slctn){
this.sendAction('changeNationalityHandler', slctn.alpha2Code);
},
}
});