Skip to content

Instantly share code, notes, and snippets.

@ioleo
Last active August 12, 2018 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ioleo/7ac5ee7869db4968d4685279440e7c0a to your computer and use it in GitHub Desktop.
Save ioleo/7ac5ee7869db4968d4685279440e7c0a to your computer and use it in GitHub Desktop.
Ember Data store problem
import DS from 'ember-data';
let ApplicationAdapter = DS.RESTAdapter.extend({
namespace: 'api',
});
export default ApplicationAdapter;
import Ember from 'ember';
export default Ember.Controller.extend({
});
import Ember from 'ember';
import { inject as service } from '@ember/service';
import { task, timeout } from "ember-concurrency";
import ItemValidations from 'twiddle/validations/item';
export default Ember.Controller.extend({
ItemValidations,
store: service(),
router: service(),
submit: task(function*(changeset) {
yield timeout(1000);
if (changeset.isValid) {
changeset.save();
let store = this.get('store');
let model = this.get('model');
let item = store.createRecord('item', model);
let router = this.get('router');
item.save().then(() => router.transitionTo('list'));
}
}),
});
import Ember from 'ember';
export default Ember.Controller.extend({
});
export default function() {
window.server = this;
this.namespace = '/api';
this.get('/items');
this.post('/items');
this.get('/items/:id');
this.put('/items/:id');
this.del('/items/:id');
}
import { Factory, faker } from 'ember-cli-mirage';
export default Factory.extend({
name() {
return faker.lorem.word();
},
color() {
return faker.lorem.word();
},
});
export default function(server) {
server.createList('item', 5);
}
import { RestSerializer } from 'ember-cli-mirage';
export default RestSerializer.extend({
normalizeIds: true
});
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';
export default Model.extend({
name: attr(),
color: attr(),
});
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: 'none',
rootURL: config.rootURL
});
Router.map(function() {
this.route('create');
this.route('list');
});
export default Router;
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return {
"name": "foo",
"color": "red"
};
}
});
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.get('store').findAll('item');
}
});
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
.form-group {
margin-top: 5px;
}
.form-group b {
display: inline-block;
width: 60px;
}
.form-group input {
border: 1px solid #d2d2d2;
border-radius: 4px;
padding: 4px 8px;
}
.form-group button {
cursor: pointer;
margin-left: 65px;
color: #fff;
background-color: #007bff;
border-color: #007bff;
display: inline-block;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
border: 1px solid transparent;
padding: .375rem .75rem;
font-size: 1rem;
line-height: 1.5;
border-radius: .25rem;
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
.form-group button:hover {
color: #fff;
background-color: #0069d9;
border-color: #0062cc;
}
h1 {
margin: 10px 0;
}
h1 small {
color: #d2d2d2;
font-size: smaller;
font-weight: normal;
}
span {
display: inline-block;
background-color: #e2e2e2;
padding: 4px 4px 1px 4px;
border-radius: 4px;
line-height: 1.2em;
vertical-align: middle;
border: 2px solid #d2d2d2;
}
span.code {
color: #00cc00;
}
span.error {
color: #cc0000;
}
<h1>Ember Data <small>store problem</small></h1>
<p>Upon saving new model, the backend (Ember Mirage) returns the model with an ID. The problem is Ember instead of updateing ID on existing model (and changeing its state to <span class="code">loaded.saved</span>) creates a new entry in the store and throws an error <span class="error">Error: Assertion Failed: 'item' was saved to the server, but the response returned the new id '106', which has already been used with another record.</span></p>
<h3>To reproduce first go to {{#link-to "create"}}Create{{/link-to}}</h3>
<h3>To view items go to {{#link-to "list"}}List{{/link-to}}</h3>
<hr />
{{outlet}}
<h3>Now submit the form, you will be redirected to list</h3>
{{#validated-form
model = (changeset model ItemValidations)
on-submit = (perform submit)
as |form|
}}
{{form.input
label = "Name"
name = "name"
required = true
}}
{{form.input
label = "Color"
name = "color"
required = true
}}
<div class="form-group">
{{form.submit label="Submit"}}
</div>
{{/validated-form}}
<h1>List of items</h1>
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Color</th>
</tr>
</thead>
<tbody>
{{#each model as |item|}}
<tr>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.color}}</td>
</tr>
{{/each}}
</tbody>
</table>
{
"version": "0.15.0",
"EmberENV": {
"FEATURES": {}
},
"ENV": {
"ember-cli-mirage": {
"enabled": true
}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js",
"ember": "3.2.2",
"ember-template-compiler": "3.2.2",
"ember-testing": "3.2.2"
},
"addons": {
"ember-data": "3.2.0",
"ember-cli-mirage": "0.4.7",
"ember-validated-form": "1.4.2",
"ember-changeset": "1.5.0-beta.0",
"ember-changeset-validations": "1.2.11",
"ember-concurrency": "0.8.19",
"ember-bootstrap": "2.0.0"
}
}
import { validatePresence, validateNumber, validateLength, validateFormat } from "ember-changeset-validations/validators";
export default {
name: [ validatePresence(true) ],
color: [ validatePresence(true) ]
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment