I've followed this example http://emberjs.com/guides/controllers/dependencies-between-controllers/ to implement a nested resource for my app but continue to receive route and type errors.
I've created my route as follows:
App.Router.map(function () {
this.resource('logs', {path: '/'}, function(){
this.resource('log', {path:'/logs/:log_id'}, function(){
this.resource('triggers');
});
});
});
My controller:
App.TriggersController = Ember.ArrayController.extend({
needs:"log"
});
Model:
App.Log = DS.Model.extend({
name: DS.attr('string'),
type: DS.attr('string'),
messages: DS.attr('string'),
triggers: DS.hasMany(App.Trigger, {async:true})
});
Child Model:
App.Trigger = DS.Model.extend({
name: DS.attr('string'),
pattern: DS.attr('string'),
isEnabled: DS.attr('boolean'),
colour: DS.attr('string'),
highlightText: DS.attr('boolean'),
invertContrast: DS.attr('boolean')
});
JSFiddle link : http://jsfiddle.net/WZp9T/11/
Click on one of the links and you should see the error in console.
("Error while loading route: TypeError {}" and "Uncaught TypeError: Cannot read property 'typeKey' of undefined" as well as a deprecation warning)
Basically, what I'm trying to achieve is:
Logs -> Log -> Log Triggers -> Trigger
Each context should remain on screen, where exactly am I going wrong?
EDIT: It seems to be a problem with this:
App.LogIndexRoute = Ember.Route.extend({
model: function (params) {
return this.store.find(params.log_id);
}
});
If I remove that piece of code I no longer receive my errors.
You need to tell the store which kind of object you want to look up. Right now you're just passing it an ID. This is probably what you're looking for:
App.LogIndexRoute = Ember.Route.extend({
model: function (params) {
return this.store.find('log', params.log_id);
}
});
Related
I have a model "Group" that has some hasMany relationships "members" and "links". I have a controller that adds a new group but i get the following error on save
"Assertion Failed: A App.Group record was pushed into the store with the value of links being '{}', but links is a hasMany relationship so the value must be an array. You should probably check your data payload or serializer."
I can fix this by returning an empty links array in the response json but i don't necessarily want this included and i don't understand why i get this error for links but not for members as that isn't included in the response either.
App.AddGroupController = Ember.ObjectController.extend({
needs: ['application'],
actions: {
submitForm: function(){
var self = this;
var model = this.get('model');
self.send('showLoading', 'Saving');
model.save().then(function(){
self.send('hideLoading');
//Go to the groups list
self.transitionToRoute('groups');
},function(error){
self.send('hideLoading');
console.log(error);
//Must supply reject callback, otherwise Ember will throw a 'backend rejected the commit' error.
});
}
}
});
App.AddGroupRoute = App.AuthenticatedRoute.extend({
model: function(){
return this.store.createRecord('group');
}
});
App.Group = DS.Model.extend({
title: DS.attr('string'),
description: DS.attr('string'),
members: DS.hasMany('groupMember'),
links: DS.hasMany('groupLink'),
});
App.GroupLink = DS.Model.extend({
title: DS.attr('string'),
link: DS.attr('string'),
});
App.GroupMember = DS.Model.extend({
first_name: DS.attr('string'),
last_name: DS.attr('string'),
email: DS.attr('string'),
profile_picture: DS.attr('string'),
});
Response from save:
{
"group":{
"id":26,
"title":"Test Group",
"description":"Dummy group description",
}
}
Im using:
Ember : 1.9.1
Ember Data : 1.13.14
I've tried writing this code in so many different ways but it returns this error:
Uncaught TypeError: Cannot read property 'createRecord' of undefined
App.StackFormComponent = Ember.Component.extend({
init: function() {
this.set('stack', Ember.Object.create());
},
actions: {
submit: function() {
var newStack = this.store.createRecord('stack', {
title: this.get('stack.title'),
location: this.get('stack.location'),
date: new Date().getTime(),
details: this.get('stack.details'),
});
newStack.save();
},
cancel: function() {
this.sendAction('cancel');
}
}
});
App.Stack = DS.Model.extend({
title: DS.attr('string'),
location: DS.attr('string'),
date: DS.attr('number'),
details: DS.attr('string')
});
Unfortunately the answers from similar questions did not help. Any idea?
Ember injects store into Routes and Controllers, but not components, so that is your problem.
You can go ahead and inject the store into your component inside initializer as follows:
Ember.onLoad('Ember.Application', function(Application) {
Application.initializer({
name: "injectStoreIntoMyComponent",
after: "store",
initialize: function(container, application) {
application.inject('component:good-test-comp', 'store', 'store:main');
}
});
});
Working example here
Inject store into components is not a good design. You can pass it as an argument {{my-component store=store}}.
Injecting store in component is not good design. Instead we need to data to components and send action to communicate with data. If you still want to include it as special case then you can simply say,
store: Ember.inject.service()
I'm trying to create an app using ember.js and ember-data, using the following versions:
DEBUG: Ember : 1.7.0
DEBUG: Ember Data : 1.0.0-beta.9
DEBUG: Handlebars : 1.2.1
DEBUG: jQuery : 2.1.0
I'm using the RESTAdapter to connect to an api I wrote using node.js.
As soon as I load the app I keep getting the following error:
Error while processing route: students undefined is not a function TypeError: undefined is not a function
at http://localhost:9000/scripts/vendor/ember-data.js:12006:34
at tryCatch (http://localhost:9000/scripts/vendor/ember.js:45818:16)
at invokeCallback (http://localhost:9000/scripts/vendor/ember.js:45830:17)
at publish (http://localhost:9000/scripts/vendor/ember.js:45801:11)
at http://localhost:9000/scripts/vendor/ember.js:29069:9
at DeferredActionQueues.invoke (http://localhost:9000/scripts/vendor/ember.js:634:18)
at Object.DeferredActionQueues.flush (http://localhost:9000/scripts/vendor/ember.js:684:15)
at Object.Backburner.end (http://localhost:9000/scripts/vendor/ember.js:147:27)
at Object.Backburner.run (http://localhost:9000/scripts/vendor/ember.js:202:20)
at apply (http://localhost:9000/scripts/vendor/ember.js:18382:27)
Here's the code I'm using (loaded in the same order I pasted it):
app.js
var App = window.App = Ember.Application.create({
LOG_ACTIVE_GENERATION: true,
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: false,
LOG_VIEW_LOOKUPS: true
});
store.js
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:3000',
serializer: DS.RESTSerializer.extend({
primaryKey: function(type) {
return '_id';
},
serializeId: function(id) {
return id.toString();
}
})
});
models/student.js
App.Student = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
nationality: DS.attr('string'),
createdAt: DS.attr('date')
});
routes/app_route.js
App.StudentsRoute = Ember.Route.extend({
model: function() {
return this.store.find('student');
}
});
router.js
App.Router.map(function () {
this.resource('students', {path: '/'});
});
And the following is the response of the API:
{
students: [
{
nationality: "Lorem",
lastName: "Doe",
firstName: "John",
_id: "53f87200f3750319b4791235",
createdAt: "2014-08-23T10:50:40.661Z"
},
{
nationality: "Lorem",
lastName: "Doe",
firstName: "John",
_id: "53f87299f3750319b4791234",
createdAt: "2014-08-23T10:50:40.661Z"
}
]
}
It looks like the store is not loading the data from the API, but the JSON data format looks fine. Any idea of what could be wrong?
Thanks!
So after searching more on Stack Overflow, I've figured out that the serializer has now to be in a separate class than the RESTAdapter, so the working code is the following:
store.js
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://localhost:3000'
});
App.ApplicationSerializer = DS.RESTSerializer.extend({
primaryKey: '_id',
serializeId: function(id) {
return id.toString();
}
});
Here's an updated answer for people using ember-cli.
ember g adapter application #=> creates app/adapters/application.js
ember g serializer application #=> creates app/serializers/application.js
In app/adapters/application.js:
import DS from 'ember-data';
export default DS.RestAdapter.extend({
host: 'http://localhost:3000'
});
In app/serializers/application.js:
import DS from 'ember-data';
export default DS.RESTSerializer.extend({
primaryKey: '_id',
serializeId: function(id) {
return id.toString();
}
});
I was getting this error, and it had nothing to do with any of the usual suspects.
In coffeescript, I had started defining a model.
App.Cost = DS.Model.extend
amount: DS.attr 'number'
active: DS.attr 'boolean'
To create a second model, I c/p my first model in and deleted the attributes:
App.Cost = DS.Model.extend
The went back and tried to run a seemingly unrelated model
localhost:3000/products
Which resulted in the error
Error while processing route: products.index
Simply making sure my model was named correctly solved the error:
App.Cost = DS.Model.extend(...)
App.Price = DS.Model.extend(...) <- instead of repeating the Cost model
This was re-produceable, so I thought it might be helpful to others.
I'm using Ember 1.4 with EmberData beta 7. My application has the routes and models shown below:
App.Router.map(function () {
this.resource('strats', {path: "/"}, function() {
this.route('strat', {path: "/strat/:strat_id"});
});
});
App.StratsStratRoute = Ember.Route.extend({
model: function(params) {
return this.store.find(params.strat_id);
}
});
var attr = DS.attr;
var belongsTo = DS.belongsTo;
var hasMany = DS.hasMany;
App.StratLeg = DS.Model.extend({
legName: attr(),
quantity: attr(),
strat: belongsTo('strat')
});
App.Strat = DS.Model.extend({
stratName: attr(),
stratLegs: hasMany('stratLeg', {async:true})
});
I can transition into the strats.strat route via link-to fine. So for example, if I transition into the strats.strat route via link-to for id="dd-put", URL displays
http://localhost:8000/em.yaws#/strat/dd-put
and everything works. But now if I hit the refresh button, or type in that same URL after first transitioning to a different route, then I get this error message on the browser console and nothing displays:
Error while loading route: Error: No model was found for 'dd-put'
at new Error (native)
at Error.Ember.Error (http://localhost:8000/js/scripts/ember-1.4.0.js:844:19)
at Ember.Object.extend.modelFor (http://localhost:8000/js/scripts/ember-data-beta7.js:9762:33)
at Ember.Object.extend.findAll (http://localhost:8000/js/scripts/ember-data-beta7.js:9364:21)
at Ember.Object.extend.find (http://localhost:8000/js/scripts/ember-data-beta7.js:9046:23)
at App.StratsStratRoute.Ember.Route.extend.model (http://localhost:8000/js/app/ed.js:47:27)
at superWrapper [as model] (http://localhost:8000/js/scripts/ember-1.4.0.js:1239:16)
at Ember.Route.Ember.Object.extend.deserialize (http://localhost:8000/js/scripts/ember-1.4.0.js:35901:19)
at http://localhost:8000/js/scripts/ember-1.4.0.js:32521:57
at http://localhost:8000/js/scripts/ember-1.4.0.js:33000:19
Anyone know what's causing this?
I'm trying out ember at my work to see if we should use it for our future applications I am doing a simple test application and I wanted to try out the relations between the models. This is the code I have that defines the models:
var App = Ember.Application.create();
App.Router.map(function () {
this.resource('index', {path: "/"}, function () {
this.resource("config", {path: "/config/:config_id"});
});
});
App.Store = DS.Store.extend();
App.Conf = DS.Model.extend({
module : DS.attr(),
reports: DS.hasMany('report'),
isClean: function() {
return !this.get('reports').isAny('isClean', false);
}.property('reports.#each')
});
App.Report = DS.Model.extend({
country: DS.attr(),
google_account_id: DS.attr(),
web_property_id: DS.attr(),
custom_source_uid: DS.attr(),
isClean: function() {
return (
this.get('country') != '' &&
this.get('google_account_id') != '' &&
this.get('web_property_id') != '' &&
this.get('custom_source_uid') != ''
);
}.property('country', 'google_account_id', 'web_property_id', 'custom_source_uid')
});
App.ApplicationAdapter = DS.RESTAdapter.extend({
host: 'http://playground.loc/battle_of_frameworks/json.php'
});
…and here is the JSON that is being loaded:
The error I get is:
Error while loading route: TypeError: Cannot set property 'store' of undefined
I Googled the problem and it's usually something about naming your models in plural (ie: App.Reports) which I'm not doing. So I am not sure what the problem is here. Can anyone give any insights?
There are several problems in your code.
Your server doesn't provide the payload expected by Ember Data. I would recommend reading this document about customizing your serializer if you can't generate the proper json payload with your backend.
Ember.js is all about convention over configuration. Right now, you are not following those conventions:
attributes are camelcased
App.Report = DS.Model.extend({
googleAccountId: DS.attr() //instead of google_account_id
});
you don't need to create the index route, it comes for free in Ember. So your router should simply look like:
App.Router.map(function () {
this.resource("config", {path: "/config/:config_id"});
});
Are you sure that your backend expects the Config to be served from /config/:config_id and not /configs/:config_id ?
You declare a config resource. The convention is to have a App.Config model and not App.Conf
In order to clean your code, you can also take advantage of computed properties to DRY your code:
App.Report = DS.Model.extend({
country: DS.attr(),
googleAccountId: DS.attr(),
webPropertyId: DS.attr(),
customSourceUid: DS.attr(),
isClean: Ember.computed.and('country', 'googleAccountId', 'webPropertyId', 'customSourceUid')
});
You also need to pay attention when defining a computed property based on an array. The isClean of Config uses isClean of Report but your computed property observes only the elements of your Report association. The correct way of writing it is:
App.Config = DS.Model.extend({
module : DS.attr(),
reports: DS.hasMany('report'),
isClean: function() {
return !this.get('reports').isAny('isClean', false);
}.property('reports.#each.isClean') //make sure to invalidate your computed property when `isClean` changes
});
I hope this helps.