Upgrading Ember project from
Ember.js 1.13.7
Ember-data 1.13.7
to
Ember.js 2.1.0
Ember-data 2.1.0
Getting Following Error
TypeError: str.replace is not a function
model (trends.js)
import DS from 'ember-data';
export default DS.Model.extend({
name:DS.attr('string',{defaultValue:''}),
daterangekey:DS.attr('number',{defaultValue:0}),
daterange:DS.attr(),
actiondata:DS.attr(),
criteria:DS.attr('string',{defaultValue:function(){
return [];
}}),
unit:DS.attr('number',{defaultValue:1}),
viewtype:DS.attr('number',{defaultValue:3})
});
Route (trends.js)
import Ember from 'ember';
export default Ember.Route.extend({
model:function()
{
return this.store.findAll('trend');
},
});
payload returning form server is
{"trends":[{"viewtype":3,"name":"Trend A","daterangekey":0,"type":1,"unit":1,"actiondata":[{"label":"action 2","id":3}],"criteria":[],"id":"1000000000027"}]}
I'm really trying to wrap my head around EmberJS but I've been stuck here on this for the last two days!
Thanks
Edited
model (trends.js)
import DS from 'ember-data';
export default DS.Model.extend({
name:DS.attr('string',{defaultValue:''}),
daterangekey:DS.attr('number',{defaultValue:0}),
daterange:DS.attr(),
actiondata:DS.attr(),
criteria:DS.attr({defaultValue:function(){
return [];
}}),
unit:DS.attr('number',{defaultValue:1}),
viewtype:DS.attr('number',{defaultValue:3})
});
Just remove "type":1 from the payload. Its bug in ember-data and it has been fixed in 1.13.12 release.
https://github.com/emberjs/data/pull/3725
criteria is an array but you define it as string.
Change like this :
criteria:DS.attr({defaultValue:function(){
return [];
}}),
Related
I am using the ember-select-2 component from https://github.com/iStefo/ember-select-2 in my Ember.js project. The list of items is fairly simple and is loaded using Ember data in the route:
setupController: function(controller, model) {
this._super(controller, model);
var otherModelsPromises = {
accomodationTypes: this.store.find('accomodation-type'),
};
Ember.RSVP.hash(otherModelsPromises).then(function(results) {
controller.set('accomodationTypes', results.accomodationTypes.get('content'));
});
And in my template, I have:
{{select-2 placeholder="Filter By" content=accomodationTypes cssClass="search-filter-dropdown"}}
And here is the JSON being returned from the URL (http://localhost:4200/api/accomodationTypes)
{"accomodationTypes":[{"id":1,"text":"Bed & Breakfast","description":"","svgid":""},
{"id":2,"text":"Self Catering","description":"","svgid":""},
{"id":3,"text":"Hotel","description":"","svgid":""},
{"id":4,"text":"Boutique Hotel","description":"","svgid":""}]}
I can see the promise being eventually resolved in route and data being returned properly. However, when I try and click on the select2 control, I get the following error in console:
Uncaught Error: Assertion Failed: select2 has no content!
If I use a static data in the controller, it works. I have a feeling that because the promise is not resolved by the time the select2 component is rendered, it fails? And it seems like the content variable is not set to use promises?
I could try and use a query, but I do not want a type ahead lookup. I just want to display a simple dropdown with multiple options and option to delete.
Am I missing something or is this a bug?
Edit: Here is the model that I'm using (models/accomodation-type.js)
import DS from 'ember-data';
export default DS.Model.extend({
text: DS.attr('string'),
description: DS.attr('string'),
svgid:DS.attr('string'),
});
Bah..I figured it out. I was doing the following two this wrong:
1. Turns out that setupController is called after the view has been rendered so the view won't have access to data when it gets rendered. So, corrected by returning a promise from model hook. This will keep the view from rendering until the models are resolved.
import Ember from 'ember';
import DS from 'ember-data';
export default Ember.Route.extend({
model: function(params) {
return Ember.RSVP.hash({
listings: this.store.find('listing', params),
accomodationTypes: this.store.find('accomodation-type')
});
},
});
Changed the select-2 component in the template to use the below:
{{select-2 placeholder="Filter by" searchEnabled=true allowClear=true multiple=true content=model.accomodationTypes cssClass="search-filter-dropdown"}}
And it works like a charm!
Currently we are upgrading our project to work with Ember 2.0 and Ember Data 2.0.
I have model which is based on fixture adapter. But when i do store.findAll(modelName) on the model, i get the following error "TypeError: serializer.normalizeResponse is not a function
at ember$data$lib$system$store$serializer$response$$normalizeResponseHelper "
Model
import DS from 'ember-data';
import FixtureData from '<from somewhere>';
var Model = DS.Model.extend({
code: DS.attr('string'),
description: DS.attr('string')
});
Model.reopenClass({
FIXTURES: FixtureData
});
export default Model;
Adapter
import DS from 'ember-data';
export default DS.FixtureAdapter.extend({
queryFixtures: function (records, query) {
return records.filter(function (record) {
for (var key in query) {
if (query.hasOwnProperty(key)) {
if (record[key] !== query[key]) {
return false;
}
}
}
return true;
});
}
});
Error Stack
TypeError: serializer.normalizeResponse is not a function
at ember$data$lib$system$store$serializer$response$$normalizeResponseHelper
(http://localhost:4201/assets/vendor.js:66323:43)
at http://localhost:4201/assets/vendor.js:66627:25
at Object.Backburner.run (http://localhost:4201/assets/vendor.js:9692:25)
at ember$data$lib$system$store$$Service.extend._adapterRun (http://localhost:4201/assets/vendor.js:71877:33)
at http://localhost:4201/assets/vendor.js:66626:15
at tryCatch (http://localhost:4201/assets/vendor.js:59683:14)
at invokeCallback (http://localhost:4201/assets/vendor.js:59698:15)
at publish (http://localhost:4201/assets/vendor.js:59666:9)
at http://localhost:4201/assets/vendor.js:39006:7
at Queue.invokeWithOnError (http://localhost:4201/assets/vendor.js:10395:18)
FixtureAdapter has been deprecated in Ember Data 1.0b19 which was released June 5 2015. This is noted in few places and tutorials have yet to catch up:
Sources:
Ember Data removal of FixtureAdapter - many of the examples tutorials will break
GitHub - Breaking Changes
Ember Data 1.0.0b19 Changelog
As an alternative to FixtureAdapter you can use Ember Mirage which fills the same role while also providing few other features.
Also on the ember-data-fixture-adapter github page, they recommend to use PretenderJS now. https://github.com/pretenderjs/pretender
I recently started learning Ember and using Ember-CLI so I'm not quite well educated about Ember Data and what array names it expects for relationships that are in sub directories in my app.
// models/server.js
import DS from 'ember-data';
export default DS.Model.extend({
serverHistory: DS.hasMany("history/server", { async: true })
});
// models/history/server.js
import DS from 'ember-data';
export default DS.Model.extend({
server: DS.belongsTo("server", { async: true })
});
I've tried returning these names from my API
server_historys_ids
server_histories_ids
history_server_ids
history_servers_ids
But I don't see an XHR request for Server history in my application. The servers itself are fetched fine.
Update
I changed my relationship name and the API is returning history ids but I'm still not getting an history json request even though I'm trying to each in the template. The game relationship data is accessible in the template and a request is successfully made.
// models/server.js
import DS from 'ember-data';
export default DS.Model.extend({
// attr's here.. not relevant
// Relationships
game: DS.belongsTo("game", { async: true }), // works
serverHistories: DS.hasMany("history/server", { async: true }) // doesn't make a request like game does.
});
I also have an adapter/history/server.js but it's only telling what namespace to use - "api".
Update 2
I think the problem may be in the way I'm calling the data to the model.
// routes/server/view/index.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
var parentModel = this.modelFor("server.view");
return this.store.query("server", { server_address: parentModel.server_address });
// return this.store.find("server", 1);
}
});
How come when I use find with an id it updates the template data and when I use query with parameters it doesn't?
Update 3
So I got my find and query problem sorted out, here's the way I got it to work: https://stackoverflow.com/a/31831667/1814027
The relationship problem still persists. I see no serverHistory data in my Ember toolbar nor a request being made to the API for it.
I beleive serverHistory is anti-conventional name for hasMany and serverHistories should be instead.
export default DS.Model.extend({
serverHistories: DS.hasMany("history/server", { async: true })
});
Then in case of ActiveModelAdapter expected server payload is:
{"server": {"id": 1, "server_history_ids": [1,2,3]}}
It doesn't depend on the fact that serverHistory is namespaced model, it depends on relation name only.
For example for model:
// models/server.js
import DS from 'ember-data';
export default DS.Model.extend({
bars: DS.hasMany("history/server", { async: true })
});
expected payload is:
{"server": {"id": 1, "bar_ids": [1,2,3]}}
Update
Working ember-cli example: https://github.com/artych/so_ember_data_subdir
Artych's answer helped me on the right path but Ember didn't want to recognise server_history_ids so I just renamed the hasMany relation to histories and returned histories: [] from my API. Now it works.. don't know why but it works.
I have a pretty simple model:
//models/build
import DS from 'ember-data';
export default DS.Model.extend({
shipments: DS.hasMany('shipment')
});
I need to update a computer property whenever a new shipment is added or removed, so I'm using my controller, like this:
//controllers/build
import Ember from 'ember';
export default Ember.Controller.extend({
init: function() {
this.get('allShips');
this.get('ships');
},
allShips: Ember.computed.alias('model.shipments'),
ships: function() {
console.log('updating ships');
}.property('model.#each.shipments')
});
I'm not consuming the computer properties in my template anywhere, I just need to keep them updated to do some computational work so I'm just getting them in the init function. I'm getting "updating ships" in the console when I'm entering the build route correctly, but after that it won't update no matter how many shipments I add or remove.
I've tried many different properties, model.ships.#each, allShips, #each.allShips, allShips.#each, and dozens of all combinations, but all were in vain. I've never had this kind of trouble with computer properties so any advice would be appreciated.
The placement of #each is incorrect - it should be after model.shipments.
As one of the comments state - if you're not accessing properties (e.g. model.shipments.#each.id then you should observe models.shipments.[].
For some reason the computed property only updates for me when returning an array - not returning a value or returning any type of value other than an array fails.
Model
//models/build
import DS from 'ember-data';
export default DS.Model.extend({
shipments: DS.hasMany('shipment')
});
Controller
//controllers/build
import Ember from 'ember';
export default Ember.Controller.extend({
init: function() {
this.get('allShips');
this.get('ships');
},
allShips: Ember.computed.alias('model.shipments'),
ships: function() {
var ships = this.get('model.shipments');
console.log('updating ships');
return [];
}.property('model.shipments.#each')
});
It's probably best to observe model.shipments.[] if you're not returning a value:
//controllers/build
import Ember from 'ember';
export default Ember.Controller.extend({
doShipsWork: function() {
console.log('updating ships');
}.observes('model.shipments.[]')
});
I have some code that needs to run on store.init.
I tried extending the default store in app/store.js, ember-cli seems to pick it up as a store, but the object in this.store is not a store
My store definition:
import DS from 'ember-data';
export default DS.Store.extend({
init:function(){
console.log('watatLoL')
}
});
According to Peter Wagenet, this has changed in Ember Data beta 19. If you're using that version or later, the file is now app/stores/application.js (or app/application/store.js if you're using pods).
Overwriting the store is the same, only the file name/location has changed. If you're using a version of Ember Data lower than beta 19, you can use the old app/store.js file.
I know this is old, but I had to answer this for another question, so I figured I would update this. By default, the Ember-CLI resolver will look for app/store.js, so you can declare your overridden store there.
// app/store.js
import DS from 'ember-data';
export default DS.Store.extend({
init: function() {
console.log('Using custom store!');
return this._super.apply(this, arguments);
}
});
The answer for > Ember 1.13:
The Store now extends the Service so we can just create the app/services/store.js and put the following code to extend/customize the store:
// app/services/store.js
import DS from 'ember-data';
export default DS.Store.extend({
init: function() {
console.log('Using custom store!');
return this._super.apply(this, arguments);
}
});
Here's a sample twiddle