Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to represent arrays within ember-data models?

Is it necessary to use DS.hasMany pointing to a DS.Model when a model contains an array? Even if the array elements are not really models (no IDs or endpoints of their own)? Is there a better way?

I am using DS.hasMany, but my extended DS.RESTAdapter is throwing me a 404 trying to access the model, even though I'm never calling find on it, and hasMany is called with { embedded: true }. I am seeing this error for the first time (apparently in connection with this model, since it goes away without it):

Uncaught Error: assertion failed: Emptying a view in the inBuffer state is not allowed and should not happen under normal circumstances. Most likely there is a bug in your application. This may be due to excessive property change notifications. ember-latest.js:43 

What does this mean and what might be causing it?

Here's the stack trace:

Ember.assert ember-latest.js:43 Ember.View.states.inBuffer.empty ember-latest.js:13644 Ember.View.Ember.Object.extend.invokeForState ember-latest.js:12257 Ember.CollectionView.Ember.ContainerView.extend.arrayWillChange ember-latest.js:14477 invokeAction ember-latest.js:3193 iterateSet ember-latest.js:3175 sendEvent ember-latest.js:3323 Ember.Array.Ember.Mixin.create.arrayContentWillChange ember-latest.js:6963 Ember.ArrayProxy.Ember.Object.extend.arrangedContentArrayWillChange ember-latest.js:9281 Ember.ArrayProxy.Ember.Object.extend._arrangedContentWillChange ember-latest.js:9235 invokeAction ember-latest.js:3193 iterateSet ember-latest.js:3175 sendEvent ember-latest.js:3323 notifyObservers ember-latest.js:1872 Ember.notifyBeforeObservers ember-latest.js:2016 propertyWillChange ember-latest.js:2594 iterDeps ember-latest.js:2077 dependentKeysWillChange ember-latest.js:2092 propertyWillChange ember-latest.js:2592 set ember-latest.js:1416 DS.Model.Ember.Object.extend.dataDidChange ember-data-latest.js:3145 Map.forEach ember-latest.js:1273 OrderedSet.forEach ember-latest.js:1145 Map.forEach ember-latest.js:1271 DS.Model.Ember.Object.extend.dataDidChange ember-data-latest.js:3128 invokeAction ember-latest.js:3193 iterateSet ember-latest.js:3175 sendEvent ember-latest.js:3323 notifyObservers ember-latest.js:1872 Ember.notifyObservers ember-latest.js:1999 propertyDidChange ember-latest.js:2632 Ember.Observable.Ember.Mixin.create.propertyDidChange ember-latest.js:7917 Ember.Observable.Ember.Mixin.create.notifyPropertyChange ember-latest.js:7930 didChangeData ember-data-latest.js:2053 Ember.StateManager.Ember.State.extend.sendRecursively ember-latest.js:15446 Ember.StateManager.Ember.State.extend.send ember-latest.js:15431 DS.Model.Ember.Object.extend.send ember-data-latest.js:3058 DS.Store.Ember.Object.extend.load ember-data-latest.js:1737 DS.Store.Ember.Object.extend.loadMany ember-data-latest.js:1763 embeddedFindRecord ember-data-latest.js:3434 hasAssociation ember-data-latest.js:3459 ComputedPropertyPrototype.get ember-latest.js:2968 get ember-latest.js:1362 getPath ember-latest.js:1484 get ember-latest.js:1355 getWithGlobals ember-latest.js:4041 Binding.connect ember-latest.js:4140 connectBindings ember-latest.js:4600 finishPartial ember-latest.js:4610 Class ember-latest.js:8315 Ember.Mixin.create.create ember-latest.js:8457 Ember.View.Ember.Object.extend.createChildView ember-latest.js:13179 Ember.View.states.inBuffer.appendChild ember-latest.js:13622 Ember.View.Ember.Object.extend.invokeForState ember-latest.js:12239 Ember.View.Ember.Object.extend.appendChild ember-latest.js:13058 EmberHandlebars.ViewHelper.Ember.Object.create.helper ember-latest.js:18687 (anonymous function) ember-latest.js:18844 (anonymous function) ember-latest.js:19043 (anonymous function) ember-latest.js:19208 (anonymous function) (anonymous function) handlebars-1.0.0.beta.6.js:1512 Ember.View.Ember.Object.extend.render ember-latest.js:12223 Ember.View.Ember.Object.extend.renderToBuffer ember-latest.js:12872 Ember.View.states.inBuffer.appendChild ember-latest.js:13625 Ember.View.Ember.Object.extend.invokeForState ember-latest.js:12239 Ember.View.Ember.Object.extend.appendChild ember-latest.js:13058 EmberHandlebars.ViewHelper.Ember.Object.create.helper ember-latest.js:18687 (anonymous function) ember-latest.js:18844 program2 (anonymous function) handlebars-1.0.0.beta.6.js:1529 Ember.View.Ember.Object.extend.render ember-latest.js:12223 Ember._HandlebarsBoundView.Ember._MetamorphView.extend.render ember-latest.js:18075 Ember.wrap.newFunc ember-latest.js:949 Ember.View.Ember.Object.extend.renderToBuffer ember-latest.js:12872 Ember.View.states.inBuffer.appendChild ember-latest.js:13625 Ember.View.Ember.Object.extend.invokeForState ember-latest.js:12239 Ember.View.Ember.Object.extend.appendChild ember-latest.js:13058 bind ember-latest.js:18129 (anonymous function) ember-latest.js:18199 (anonymous function) ember-latest.js:18271 program1 (anonymous function) handlebars-1.0.0.beta.6.js:1529 Ember.View.Ember.Object.extend.render ember-latest.js:12223 Ember.View.Ember.Object.extend.renderToBuffer ember-latest.js:12872 Ember.ContainerView.Ember.View.extend.render ember-latest.js:14078 Ember.View.Ember.Object.extend.forEachChildView ember-latest.js:12486 Ember.ContainerView.Ember.View.extend.render ember-latest.js:14077 Ember.wrap.newFunc ember-latest.js:949 Ember.View.Ember.Object.extend.renderToBuffer ember-latest.js:12872 Ember.View.states.inBuffer.appendChild ember-latest.js:13625 Ember.View.Ember.Object.extend.invokeForState ember-latest.js:12239 Ember.View.Ember.Object.extend.appendChild ember-latest.js:13058 EmberHandlebars.ViewHelper.Ember.Object.create.helper ember-latest.js:18687 (anonymous function) ember-latest.js:18844 (anonymous function) ember-latest.js:19043 (anonymous function) ember-latest.js:19208 (anonymous function) (anonymous function) handlebars-1.0.0.beta.6.js:1512 Ember.View.Ember.Object.extend.render ember-latest.js:12223 Ember.View.Ember.Object.extend.renderToBuffer ember-latest.js:12872 Ember.ContainerView.Ember.View.extend.render ember-latest.js:14078 Ember.View.Ember.Object.extend.forEachChildView ember-latest.js:12486 Ember.ContainerView.Ember.View.extend.render ember-latest.js:14077 Ember.wrap.newFunc ember-latest.js:949 Ember.View.Ember.Object.extend.renderToBuffer ember-latest.js:12872 Ember.View.states.inBuffer.appendChild ember-latest.js:13625 Ember.View.Ember.Object.extend.invokeForState ember-latest.js:12257 Ember.View.Ember.Object.extend.appendChild ember-latest.js:13058 EmberHandlebars.ViewHelper.Ember.Object.create.helper ember-latest.js:18687 (anonymous function) ember-latest.js:18844 (anonymous function) ember-latest.js:19624 (anonymous function) ember-latest.js:18167 (anonymous function) (anonymous function) handlebars-1.0.0.beta.6.js:1512 Ember.View.Ember.Object.extend.render ember-latest.js:12223 Ember.View.Ember.Object.extend.renderToBuffer ember-latest.js:12872 Ember.View.Ember.Object.extend.createElement ember-latest.js:12669 Ember.View.states.preRender.insertElement ember-latest.js:13558 Ember.View.Ember.Object.extend.invokeForState ember-latest.js:12257 invoke ember-latest.js:3428 iter ember-latest.js:3475 RunLoop.flush ember-latest.js:3531 RunLoop.end ember-latest.js:3447 Ember.run.end ember-latest.js:3639 autorun ember-latest.js:3705 

Thanks for any help.

Update: This fiddle works (with example from docs), but how could those objects be represented if the tags aren't real models (i.e. don't have IDs)?

like image 644
dechov Avatar asked Aug 28 '12 22:08

dechov


1 Answers

Well... It was a little bit difficult but mixing all answers in this post I made it work.

Firstly, you should create a transform for the new type "array":

DS.ArrayTransform = DS.Transform.extend({   deserialize: function(serialized) {     return (Ember.typeOf(serialized) == "array")         ? serialized          : [];   },    serialize: function(deserialized) {     var type = Ember.typeOf(deserialized);     if (type == 'array') {         return deserialized     } else if (type == 'string') {         return deserialized.split(',').map(function(item) {             return jQuery.trim(item);         });     } else {         return [];     }   } });  App.register("transform:array", DS.ArrayTransform); 

Now, in your model, just use it as another attr:

App.myModel = Ember.Model.extend({     name : DS.attr('string'),     cont : DS.attr('array') } 

And we are done. Remember, when adding elements to the array, to use pushObject.

In a controller:

this.get('model.cont').pushObject('new Item'); 

I hope this helps someone.

like image 121
Jorgeblom Avatar answered Sep 17 '22 15:09

Jorgeblom