I have problem creating record on one-to-many relationship. I use Ember 1.7 with Ember Data 1.0.0-beta.10.
app/models/transaction.js
import DS from 'ember-data';
var Transaction = DS.Model.extend({
code: DS.attr('string'),
created_at: DS.attr('date', {
defaultValue: function() { return new Date(); }
}),
customer: DS.belongsTo('customer', { embedded: 'always', async: true }),
details: DS.hasMany('transactiondetail', { embedded: 'always', async: true }),
is_cash_payment: DS.attr('boolean')
});
export default Transaction;
app/models/transactiondetail.js
import DS from 'ember-data';
var TransactionDetail = DS.Model.extend({
item: DS.belongsTo('item', { embedded: 'always', async: true }),
max_returned_at: DS.attr('date'),
returned_at: DS.attr('date'),
price: DS.attr('number')
});
export default TransactionDetail;
app/serializers/transaction.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
customer: { serialize: 'records', deserialize: 'id' },
details: { serialize: 'records', deserialize: 'ids' }
}
});
app/serializers/transactiondetail.js
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
item: { serialize: 'records', deserialize: 'id' },
}
});
app/controllers/transaction/create.js
import Ember from 'ember';
export default Ember.ObjectController.extend(, {
needs: ['transactions'],
transactionCode: '',
dateNow: new Date(),
maxReturnedAt: maxReturnedAt,
selectedItem: [],
selectedCustomer: null,
totalPrice: totalPrice,
payValue: 0,
change: 0,
isCashPayment: true,
actions: {
create: function() {
var self = this;
var record = this.store.createRecord('transaction', {
code: this.get('transactionCode'),
customer: this.get('selectedCustomer'),
is_cash_payment: this.get('isCashPayment')
});
this.get('selectedItem').forEach(function( item ) {
var transactionDetail = self.store.createRecord('transactiondetail', {
item: item,
max_returned_at: self.get('maxReturnedAt'),
price: item.get('price')
});
record.get('details').then(function(selectedRecord) {
selectedRecord.pushObject( transactionDetail );
});
});
record.save().then( function() {
self.get('controllers.transactions.model').pushObject({});
self.clearForm();
self.transitionToRoute('transactions');
});
},
goBack: function() {
this.transitionToRoute('transactions');
},
}
});
If I do create record, I got an error like this.
Error: Assertion Failed: The content property of DS.PromiseArray should be set before modifying it
at new Error (native)
at Error.EmberError (http://machine.dev:4200/assets/vendor.js:26712:23)
at Object.Ember.assert (http://machine.dev:4200/assets/vendor.js:16896:15)
at EmberObject.extend._replace (http://machine.dev:4200/assets/vendor.js:45514:15)
at EmberObject.extend._insertAt (http://machine.dev:4200/assets/vendor.js:45529:14)
at EmberObject.extend.pushObject (http://machine.dev:4200/assets/vendor.js:45573:14)
at apply (http://machine.dev:4200/assets/vendor.js:31554:27)
at superWrapper [as pushObject] (http://machine.dev:4200/assets/vendor.js:31132:15)
at eval (pw-store/controllers/transactions/create.js:74:35)
at Array.forEach (native) vendor.js:27637logToConsole vendor.js:27637RSVP.onerrorDefault vendor.js:41089__exports__.default.trigger vendor.js:59652Promise._onerror vendor.js:60651publishRejection vendor.js:58914(anonymous function) vendor.js:42243DeferredActionQueues.invoke vendor.js:13808DeferredActionQueues.flush vendor.js:13858Backburner.end vendor.js:13321Backburner.run vendor.js:13376apply vendor.js:31557run vendor.js:30173__exports__.default.EmberObject.extend._bubbleEvent vendor.js:50350(anonymous function) vendor.js:50298jQuery.event.dispatch vendor.js:4759jQuery.event.add.elemData.handle vendor.js:4427
Uncaught Error: Assertion Failed: Error: Assertion Failed: The content property of DS.PromiseArray should be set before modifying it
UPDATE
I have update my Ember Data to 1.0.0-beta.11 as suggested by Kingpin2k, but I got undefined error (see my comment below). I guess I do mistake on model and/or serializer but I have no idea how to fix it. Any help?
Related
I am having issue using ember-cli-mirage. My instance of mirage is configured to use the RESTSerializer and the EmbeddedRecordsMixin for relationships. I am able to get records with relationship without a problem, however when I save the parent record I get the following error coming from the ember-data code:
RangeError: Maximum call stack size exceeded
Weirdly enough, if I just removed the EmbeddedRecordsMixin everything works fine. Is there some restriction or special thing you need to do use the EmbeddedRecordsMixin with mirage
// models/artist.js
import DS from 'ember-data';
const { attr, hasMany, Model } = DS;
export default Model.extend({
name: attr('string'),
genre: attr('string'),
country: attr('string'),
bio: attr(),
albums: hasMany('album', {
async: false
}),
songs: hasMany('song', {
async: false
})
});
// serializers/artist.js
import DS from 'ember-data';
const { RESTSerializer } = DS;
export default RESTSerializer.extend(EmbeddedRecordsMixin, {
attrs: {
albums: {
embedded: 'always'
},
songs: {
embedded: 'always'
}
}
});
// mirage/models/artist.js
import { Model, hasMany } from 'ember-cli-mirage';
export default Model.extend({
albums: hasMany(),
songs: hasMany()
});
// mirage/factories/artist.js
import { Factory, faker } from 'ember-cli-mirage';
export default Factory.extend({
name() {
return faker.name.findName();
},
genre() {
return faker.hacker.noun();
},
country() {
return faker.address.country();
},
bio() {
return faker.lorem.sentence();
},
afterCreate(artist, server) {
server.createList('album', 3, { artist });
server.createList('song', 3, { artist });
}
});
// mirage/serializers/artist.js
import { RestSerializer } from 'ember-cli-mirage';;
export default RestSerializer.extend({
embed: true,
include: ['songs', 'albums']
});
Ember serializer test below is failing with “Cannot read property ‘push’ of null”.
I am using Pretender mock server library. The test is failing when I'm calling a store.findRecord()
Note how there are no relationships in the assignment model/serializer, which is why it's confusing that it's throwing the following error:
Click here to see the error that's getting returned
assignment serializer:
import DS from 'ember-data';
const { JSONAPISerializer } = DS;
export default JSONAPISerializer.extend({
attrs: {
autoPassReviewerNote: 'autoPassReviewerNote',
dateOfCreation: 'date_of_creation',
displayType: 'displayType',
lastUpdate: 'last_update',
moduleItem: 'moduleItem',
submissionType: 'submissionType'
}
});
assignment model:
import DS from 'ember-data';
const {
Model,
attr
} = DS;
export default Model.extend({
title: attr('string'),
submissionType: attr('string'),
description: attr('string'),
completed: attr('boolean'),
displayType: attr('string'),
dateOfCreation: attr('string'),
lastUpdate: attr('string'),
autopass: attr('boolean'),
moduleItem: attr('object')
});
serializer test (which is failing):
import { moduleForModel, test } from 'ember-qunit';
import Pretender from 'pretender';
import Ember from 'ember';
const {
run
} = Ember;
var server;
moduleForModel('assignment', 'Unit | Serializer | assignment', {
needs: [
'serializer:assignment'
],
beforeEach: function() {
server = new Pretender(function() {
// eslint-disable-next-line ember/use-ember-get-and-set
this.get('/assignments/:id', function() {
data: {
type: 'assignment',
id: 98,
attributes: {
title: 'dfgdfg',
submissionType: 'dfgdf',
displayType: 'dfgdfg',
date_of_creation: 'sdfgsdfg',
last_update: 'fgdgd'
}
}
};
return [ 200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ];
});
});
},
afterEach: function() {
server.shutdown();
}
});
test('testing assignment serializer', function(assert) {
var checkAttrSerialization = (assignment) => {
assert.equal(assignment, true);
}
let store = this.store();
run(() => {
return store.findRecord('assignment', 98).then((assignment) => checkAttrSerialization(assignment));
});
});
I'm getting this error when trying to consume the json from the backend.
I'm using Ember CLI version 2.5.0 and the RestAdapter.
Here's my routes/products/index.js looks like:
export default Ember.Route.extend({
actions: {
[...]
},
model: function() {
return this.store.findAll('product');
}
});
And here's what my json looks like:
{
"products":[
{
"id":9,
"name":"Product A",
"price_cents":1500,
"margin_cents":0,
"commission":0,
"expiration":null,
"track_stock":false,
"stock_amount":5,
"brand":{
"id":2,
"name":"SuperPet"
},
"group":{
"id":1,
"name":"Group A"
}
},
{
"id":8,
"name":"Product B",
"price_cents":1500,
"margin_cents":0,
"commission":0,
"expiration":null,
"track_stock":false,
"stock_amount":5,
"brand":{
"id":1,
"name":"Whiskas"
},
"group":{
"id":1,
"name":"Group B"
}
}
],
"meta":{
"pagination":{
"per_page":null,
"total_pages":4,
"total_objects":10
}
}
}
And by request, here's the model:
import DS from 'ember-data';
const { attr, belongsTo } = DS;
export default DS.Model.extend({
name: attr('string'),
priceCents: attr('number'),
marginCents: attr('number'),
comission: attr('number'),
expiration: attr('date'),
trackStock: attr('boolean'),
stockAmount: attr('number'),
brand: belongsTo('brand')
});
I was having the same issue. This worked for me:
//app/serializers/product.js
import DS from 'ember-data';
import Ember from 'ember';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin,{
attrs: {
brand: { embedded: 'always' },
group: { embedded: 'always'}
}
});
You have the brand: belongsTo('brand')
but you forgot the group: belongsTo('group')
also .. these two ( brand, group ) have to be declared as embedded with the DS.EmbeddedRecordsMixin in the product serializer if you are going to embed them this way
I am trying to create and save a model in Ember but only the first entry in my form is saving leaving the others blank.
Before saving all of the models attributes are correct. (shown with logs)
Any help greatly appreciated!
My Model is:
import DS from 'ember-data';
export default DS.Model.extend({
endpoint: DS.attr('string'),
playerVersion: DS.attr('string'),
createdAt: DS.attr('date'),
updatedAt: DS.attr('date')
});
My Route is:
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.createRecord('account');
}
});
My Controller is:
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
save: function() {
var _this = this;
var model = this.get('model');
console.log(model.get('endpoint')); //Shows correct endpoint
console.log(model.get('playerVersion')); //Shows correct playerVersion
model.save().then(function(account) {
console.log(model.get('endpoint')); //Shows correct endpoint
console.log(model.get('playerVersion')); //Shows nothing
_this.transitionToRoute('accounts.index');
});
return false;
}
}
});
UPDATE - Was some settings needed on the custom Serializer needed.
export default JsonApiSerializer.extend({
keyForAttribute: function(key) {
//return Ember.String.dasherize(key);
return Ember.String.camelize(key);
},
keyForRelationship: function(key) {
//return Ember.String.dasherize(key);
return Ember.String.camelize(key);
},
keyForSnapshot: function(snapshot) {
//return Ember.String.dasherize(snapshot.typeKey);
return Ember.String.camelize(snapshot.typeKey);
},
});
Here is the code app/routes/profile.js
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
model: function() {
var _this = this;
return Ember.$.get('/user/profile').then(function(data)
_this.store.push('profile', data);
});
}
});
app/models/profile.js
import DS from "ember-data";
export default DS.Model.extend({
name: DS.belongsTo('name')
});
app/models/name.js
import DS from "ember-data";
export default DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string')
});
app/serializers/profile.js
import DS from "ember-data";
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
name: {embedded: 'always'}
}
});
I'm getting an error cannot read property 'typeKey' of undefined
This is the JSON response from server.
{
"id":"1",
"name":{
"id":"1",
"firstName":"first name",
"lastName":"last name"
}
}
You'll need the server to return the payload wrapped in a type object:
{
"profiles": [{
"id":"1",
"name":{
"id":"1",
"firstName":"first name",
"lastName":"last name"
}
}]
}