ember-select-2
ember-select-2 copied to clipboard
Multi-Select with hasMany attribute error
The error Uncaught Error: Cannot set read-only property "<propertyName>" on object is thrown by Ember when selecting items from the available options using ember-select-2 when selection is set to a an attribute on a model that is defined as a hasMany attribute.
Here is a SO article that appears relevant: http://stackoverflow.com/questions/24184706/ember-data-createrecord-with-hasmany-relationship-without-saving
And a closed Ember Data issue that seems relevant as well: https://github.com/emberjs/data/issues/2233
I switched to ember-select-2 after a couple years of rolling my own solution pre-ember-cli. I decided to go with this component due to its simplicity and to simplify my components. I thought this would just work but it appears to have at least 1 issue for a very common use-case.
I am also facing the same issue. @abobwhite Have you found any solution ?
I thought about creating a pull request but I do not know how to test local changes with ember addon. What I did instead was to manually create an array which contains ids for the selection property and added an observer to listen for changes on that array to push/remove objects from the hasMany itself. It was actually a pain in the butt .... but it worked. I would love to get the real fix into this addon, though.
@abobwhite Even i was thinking of the same approach. Even though is not a clean solution, glad that it worked. Will be doing the same i guess.
I'm having the same issue. I'll fork the repo and look into fixing this.
Took a look, it would require changing the architecture of the plugin quite a bit. If you checkout this line here, .set is called on the value property, which in our case is a relationship. Since you can't call .set on a relationship, this is where the error happens.
Fixing it would mean tracking the before/after state of each change, detecting what was added or removed, and then performing the right action on each item.
Any thoughts on this @iStefo? After switching to this plugin I've just come across this and it seems like it'd be a pretty common use case :+1:
@adamlc I've just switched to ember-cli-selectize, which supports relationships out of the box.
For everyone experiencing issue with hasMany and select2, I have a workaround that worked very well for me. Let's say we have post that can have many tags, and we use select2 to choose tags from list. We will need custom component that extends select2 (for instance tags-search) in which we'll override didSelect method, and computed property in post model, that will return array of tags' names. Final code can look a bit like this: In template:
tags-search [
content=tags
value=model.tagsList
multiple=true
model=model ]
instead of content you can use query, it won't change the outcome. For displayed value in select box we're using computed property that returns list of tag names (at the bottom of post). Model (in this case post) must be passed to component - its tags property will be set to whatever was selected.
Search-tags component:
import Select2Component from "your-app-name/components/select-2";
export default Select2Component.extend({
didSelect(values, component) {
var post = component.get("model");
post.set("tags", values);
return;
}
})
Computed property in post model:
tagsList: Ember.computed("tags", function() {
var list = [];
this.get("tags").forEach(function(tag) {
var tagName=tag.get("name");
list.push(tagName);
})
return list;
})
Hope this helps :)
Very similar to @angouleme's solution, here's a util that removes the need for a custom component. This will keep your hasMany in sync with select2 via computed property get/set:
Usage:
# on Post
tagSelects: selectableChildren('tags')
# on Tag
asSelection: ->
name: @get('name'), id: @get('id')
<select-2 value=model.tagSelects...
The util:
selectableChildren = (associationName) ->
Ember.computed "#{associationName}.@each",
get: (key) ->
@get(associationName).map (assn) -> assn.asSelection()
set: (key, selections) ->
@set(associationName, [])
for selection in selections
child = @store.createRecord(@relationshipFor(associationName).type, selection)
@get(associationName).addObject(child)
@get(key)
`export default selectableChildren`
I think we're all covered with the alternative solutions but the main thing here is that Ember Data is a core component of the Ember world and if this addon is to be taken seriously and used by more people, this support just needs to be added so we don't need lengthy workarounds
any updates on this?