Overwrite DS.Store ember-cli - ember.js

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

Related

ember-pouch: does not load hasMany relationship when the belongsTo side is polymorphic

I have an ember-data app that uses the ember-pouch adapter for local & remote storage.
I am unable to load hasMany relationships when the belongsTo side is polymorphic. I've played with async: true/false and donstsave: true/false options on the hasMany side, to no avail.
The setup:
post can have many comments.
comment can have many comments.
comment belongs to commentable.
// app/models/post.js
import DS from 'ember-data';
import { Model } from 'ember-pouch';
export default Model.extend({
DS.hasMany('comment', { inverse: 'commentable' });
});
// app/models/comment.js
import DS from 'ember-data';
import { Model } from 'ember-pouch';
export default Model.extend({
DS.belongsTo('commentable', { polymorphic: true });
DS.hasMany('comment', { inverse: 'commentable' });
});
The Problem
Calling post.get('comments') loads nothing. If comments are loaded into the store separately, however, then post is able to correctly render comments:
// In the console (being mindful that `post.get('comments')` returns a promise)
const post = store.findRecord('post', '123');
post.get('comments').get('length'); // => 0
store.findAll('comment');
post.get('comments').get('length'); // => 12
What worked for me during an experiment (although I was heavily modifying ember-pouch within the adapter) was using post.get('comments').content.length but don't ask me why this is so and if it is supposed to be that way ...
EDIT:
It seems the problem is that the data is not loaded at that time. So probably something like post.get('comments').then(function() {this.debug(post.get('comments').length})) will work.

str.replace is not a function in ember 2.1.0

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 [];
}}),

What array name does Ember Data expect for sub directory models?

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.

Computer Property not updating on hasMany

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.[]')
});

Ember CLI - Error when using moment.js in route

I have imported moment.js into my project and it seems to work just fine in my controllers but for some reason it is not working in my routes.
Controller:
// controllers/users.js
import Ember from 'ember';
export default Ember.Controller.extend({
date: function() {
alert(moment().format('X'));
}.property()
...
});
Route:
// routes/users.js
// (Error: /routes/users.js: line 5, col 29, 'moment' is not defined.
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
var data = { start: moment().startOf('month').startOf('day').format('X') };
return this.store.find('event', data);
}
});
Brocfile:
var app = new EmberApp();
app.import('vendor/moment/moment.js');
I guess this is a JsHint Error. You may want to add the following comment to your Route code.
/* global moment:true */
import Ember from "ember";
....
Also (from ember-cli documentation):
If you want to use external libraries that write to a global namespace (e.g. moment.js), you need to add those to the predef section of your project’s .jshintrc file and set its value to true. If you use the lib in tests, need to add it to your tests/.jshintrc file, too.
Then you don't have to do it to every file your using moment.js in.