Ember-data keeps saying "no mdel was found for" - ember.js

I am trying to write a EMberjs application, using Ember-Data. also, require.js and coffeescript. despite following each and every guide and discussion I could find, i am still getting 'no model was found for' error.
here are my classes:
main.coffee (entry point for require.js):
require.config
paths:
jQuery: "../javascript/jquery-2.1.1.min"
handlebars: "../javascript/handlebars-v1.3.0"
ember: "../javascript/ember.prod"
ember_data: "../javascript/ember-data.prod",
shim:
ember:
deps: ["jQuery", "handlebars"]
exports: "Ember"
'ember_data':
deps:[ 'ember'],
exports:'DS'
require ["app", "router"], (app, Router) ->
app.deferReadiness()
Router()
app.advanceReadiness()
return
app.coffee:
define "app", ["ember", "ember_data"], (Ember) ->
window.app = Ember.Application.create()
app.ApplicationAdapter = DS.FixtureAdapter.extend()
app
router.coffee:
define "router", ["app", "ember-data", "ember", "models/person"], (app) ->
->
app.Router.map ->
#route 'home', path: "/"
#resource('person', { path: 'person'}, ->
#route('details', { path: ':slug' })
return
)
return
app.HomeRoute = Ember.Route.extend
model: ->
app.PersonRoute = Ember.Route.extend
model: () ->
return #store.find("Person")
models/person.coffee:
class app.Person extends DS.model
first: DS.attr("string")
app.Person.FIXTURES = { person: [
{
id: 1,
first: "first_1"
},
{
id: 2,
first: "first_2"
}
]}
but when i go to http://localhost:9000/#/person, i get this:
Error while processing route: person.index" "No model was found for 'Person'" "EmberError#http://localhost:9000/assets/javascript/ember.prod.js:13949:17
Store<.modelFor#http://localhost:9000/assets/javascript/ember-data.prod.js:11264:1
Store<.findAll#http://localhost:9000/assets/javascript/ember-data.prod.js:10845:20
Store<.find#http://localhost:9000/assets/javascript/ember-data.prod.js:10476:1
app.PersonRoute<.model#http://localhost:9000/assets/javascript/router.js:24:16
apply#http://localhost:9000/assets/javascript/ember.prod.js:19296:1
superWrapper#http://localhost:9000/assets/javascript/ember.prod.js:18867:15
Route<.deserialize#http://localhost:9000/assets/javascript/ember.prod.js:24467:16
applyHook#http://localhost:9000/assets/javascript/ember.prod.js:45215:16
HandlerInfo.prototype.runSharedModelHook#http://localhost:9000/assets/javascript/ember.prod.js:43237:22
UnresolvedHandlerInfoByParam<.getModel#http://localhost:9000/assets/javascript/ember.prod.js:43463:16
bind/<#http://localhost:9000/assets/javascript/ember.prod.js:45089:16
tryCatch#http://localhost:9000/assets/javascript/ember.prod.js:45538:16
invokeCallback#http://localhost:9000/assets/javascript/ember.prod.js:45550:17
publish#http://localhost:9000/assets/javascript/ember.prod.js:45521:11
#http://localhost:9000/assets/javascript/ember.prod.js:28956:9
DeferredActionQueues.prototype.invoke#http://localhost:9000/assets/javascript/ember.prod.js:679:11
DeferredActionQueues.prototype.flush#http://localhost:9000/assets/javascript/ember.prod.js:749:15
Backburner.prototype.end#http://localhost:9000/assets/javascript/ember.prod.js:135:11
createAutorun/backburner._autorun<#http://localhost:9000/assets/javascript/ember.prod.js:521:9
" ember.prod.js:15069
any idea anyone?
EDIT:
it seems like if I move the person.coffee file from /models to the same level as main and App, and change the 'define' line in the router accordingly, it works as expected. Still a mystery to me :(

I'm not 100% sure, but the problem might be in wrong formatted fixtures for App.Person.
Could you rewrite fixtures like this?
app.Person.FIXTURES = [
{
id: 1,
first: "first_1"
},
{
id: 2,
first: "first_2"
}
]

You should be defining your fixtures using reopenClass, so along these lines:
App.Documenter.reopenClass({
FIXTURES: [
{ id: 1, firstName: 'Trek', lastName: 'Glowacki' },
{ id: 2, firstName: 'Tom' , lastName: 'Dale' }
]
});
as seen in the example here http://emberjs.com/guides/models/the-fixture-adapter/
The approach you're using is out of date.

Related

Accessing model properties in Controller - Ember

So, I'm trying to access my model properties in controller.
Controller:
dashobards: [
{ id: 12, name: 'test' },
{ id: 17, name: 'test2' },
];
In route I have model named dashboards
return Ember.RSVP.hash({
dashboards: this.store.findAll('dashboard'),
}).then((hash) => {
return Ember.RSVP.hash({
dashboards: hash.dashboards
});
}, self);
I wanna have result in controller like this:
dashboards: [
{ id: 12, name: 'test' },
{ id: 17, name: 'test2' },
{ id: 17, name: 'test1' },
{ id: 20, name: 'test20' },
];
In controller I am trying to access this model like this:
this.dashborads = this.get(model.dashobards)
And it's not working, is there any other way of doing that?
Another update How to access complex object which we get it from server in ember data model attibute,
Created twiddle to demonstrate
define attribute with DS.attr(),
export default Model.extend({
permissions:DS.attr()
});
route file,
model(){
return this.store.findAll('dashboard');
}
Your server response should be like,
data: [{
type: 'dashboard',
id: 1,
attributes: {
permissions: {'name':'role1','desc':'description'}
}
}]
hbs file,
{{#each model as |row| }}
Name: {{row.permissions.name}} <br/>
Desc: {{row.permissions.desc}} <br />
{{/each}}
Update:
Still I am not sure about the requirement, Your twiddle should be minimalized working twiddle for better understanding..anyway I will provide my observation,
1.
model(params) {
this.set('id', params.userID);
const self = this;
return Ember.RSVP.hash({
dashboards: this.store.findAll('dashboard'),
user: this.store.findRecord('user', params.userID)
}).then((hash) => {
return Ember.RSVP.hash({
user: hash.user,
dashboards: hash.dashboards
});
}, self);
}
The above code can be simply written like
model(params) {
this.set('id', params.userID);
return Ember.RSVP.hash({
dashboards: this.store.findAll('dashboard'),
user: this.store.findRecord('user', params.userID)
});
}
Its good to always initialize array properties inside init method. refer https://guides.emberjs.com/v2.13.0/object-model/classes-and-instances/
For removing entry from array,
this.dashboard.pushObject({ 'identifier': '', 'role': '' }); try this this.get('dashboard').pushObject({ 'identifier': '', 'role': '' });.
if possible instead of plain object you can use Ember.Object like
this.get('dashboard').pushObject(Ember.Object.create({ 'identifier': '', 'role': '' }));
For removing entry.
removeDashboard(i) {
let dashboard = Ember.get(this, 'dashboard');
Ember.set(this, 'dashboard', dashboard.removeObject(dashboard[i]));
}
The above code can be written like, since i is an index
removeDashboard(i) {
this.get('dashboard').removeAt(i)
}
Just do return this.store.findAll('dashboard'); in route model hook, and dont override setupController hook, then in hbs you should be able to access model that will represent RecordArray. you can have a look at this answer for how to work with this.

Ember Data: saving polymorphic relationships

I'm having trouble saving "hasMany" polymorphic records in Ember Data (1.0.0-beta.15). It looks as if Ember Data isn't setting the "type" property of the polymorphic relationship. Relationships in serialized records look like:
"roles": ["1", "2"]
When I expect them to look more like:
"roles":[{
"id": "1",
"type": "professionalRole"
}, {
"id": "2",
"type": "personalRole"
}
];
I see the following error in the console:
TypeError: Cannot read property 'typeKey' of undefined
If the records come back from the server in the expected format, all is well. The error only occurs when Ember Data creates the relationship.
I experience this using the FixtureAdapter, LocalStorageAdapter, and the RESTAdapter. I've read every piece of documentation I can find on the subject, but I cannot see my mistake.
I've created a CodePen to demonstrate the problem, but I'll also paste that code below.
window.App = Ember.Application.create();
App.ApplicationAdapter = DS.FixtureAdapter;
App.Person = DS.Model.extend({
name: DS.attr(),
roles: DS.hasMany('role')
});
App.Role = DS.Model.extend({
title: DS.attr(),
person: DS.belongsTo('person', {
polymorphic: true
})
});
App.ProfessionalRole = App.Role.extend({
rank: DS.attr()
});
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
var person = this.store.createRecord('person', {
name: 'James'
});
var role = this.store.createRecord('professionalRole', {
title: 'Code Reviewer',
rank: 'Expert'
});
var promises = Ember.RSVP.hash({
person: person.save(),
role: role.save()
});
promises.catch(function() {
controller.set('initialSaveResult', 'Failure');
});
promises.then(function(resolved) {
controller.set('initialSaveResult', 'Success!');
var resolvedPerson = resolved.person;
var resolvedRole = resolved.role;
// Either/both of these break it
//resolvedRole.set('person', resolvedPerson);
resolvedPerson.get('roles').addObject(resolvedRole);
var innerPromises = Ember.RSVP.hash({
person: resolvedPerson.save(),
role: resolvedRole.save()
});
innerPromises.catch(function() {
controller.set('secondSaveResult', 'Failure');
});
innerPromises.then(function() {
controller.set('secondSaveResult', 'Success!');
});
});
}
});
App.ApplicationController = Ember.Controller.extend({
initialSaveResult: "Loading...",
secondSaveResult: "Loading..."
});

How to correctly access a parent controllers data (model) in nested resources?

I have a little EmberJS app to test things out hot to do nested resources. Sometimes accessing a parent routes/controllers data work, other times not.
Most likely this is due to a oversight on my part with how EmberJS does its magic.
Here is the app:
window.App = Ember.Application.create();
App.Router.map(function() {
this.resource('items', function() {
this.resource('item', {path: ':item_id'}, function() {
this.resource('subitems');
});
});
});
App.ApplicationController = Ember.Controller.extend({
model: {
items: [
{
id: 1,
name: 'One',
subitems: [
{
id: 1,
name: 'One One'
}, {
id: 2,
name: 'One Two'
}
]
}, {
id: 2,
name: 'Two',
subitems: [
{
id: 3,
name: 'Two One'
}, {
id: 4,
name: 'Two Two'
}
]
}
]
}
});
App.ItemsRoute = Ember.Route.extend({
model: function() {
return this.controllerFor('Application').get('model.items')
}
});
App.ItemRoute = Ember.Route.extend({
model: function(params) {
var items = this.controllerFor('Items').get('model')
var item = items.filterBy('id', parseInt(params.item_id))[0]
return item
}
});
App.SubitemsRoute = Ember.Route.extend({
model: function(params) {
var item = this.controllerFor('Item').get('model')
var subitems = item.get('subitems')
return subitems
}
});
http://jsfiddle.net/maxigs/cCawE/
Here are my questions:
Navigating to items/1/subitems throws an error:
Error while loading route: TypeError {} ember.js:382
Uncaught TypeError: Cannot call method 'get' of undefined test:67
Which i don't really get, since apparently the ItemController loads its data correctly (it shows up) and the same construct works for the ItemsRoute as well to get its data.
Since i don't have access to the parents routes params (item_id) i have no other way of re-fetching the data, even though directly accessing the data from ApplicationController works fine.
Why do i have define the root data in a controller not route?
Moving the model definition from ApplicationController to ApplicationRoute, does not work.
Conceptually, as far as i understand it, however this should even be the correct way to do it, since everywhere else i define the mode data for the controller int he route.
Or should the whole thing be better done via the controllers needs-api? As far as i understood the needs are more for only accessing extra data within the controller (or its view) but the routers job is to provide the model.
1. Navigating to items/1/subitems throws an error:
Your model is just a javascript object so there isn't a method get to fetch the data. You can access the subitems by just executing item.subitems.
Also the argument of controllerFor() should be lower case.
For instance:
this.controllerFor('application')
2. Why do i have define the root data in a controller not route?
You can set the model from the route in the setupController method.
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('model', { ... });
}
});
http://jsfiddle.net/Y9kZP/
After some more fiddling around here is a working version of the example in the question:
window.App = Ember.Application.create();
App.Router.map(function() {
this.resource('items', function() {
this.resource('item', {path: ':item_id'}, function() {
this.resource('subitems');
});
});
});
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return Ember.Object.create({
items: [
Ember.Object.create({
id: 1,
name: 'One',
subitems: [
{
id: 1,
name: 'One One'
}, {
id: 2,
name: 'One Two'
}
]
}), Ember.Object.create({
id: 2,
name: 'Two',
subitems: [
{
id: 3,
name: 'Two One'
}, {
id: 4,
name: 'Two Two'
}
]
})
]
})
}
});
App.ItemsRoute = Ember.Route.extend({
model: function() {
return this.modelFor('application').get('items')
}
});
App.ItemRoute = Ember.Route.extend({
model: function(params) {
return this.modelFor('items').findProperty('id', parseInt(params.item_id))
}
});
App.SubitemsRoute = Ember.Route.extend({
model: function(params) {
return this.modelFor('item').get('subitems')
}
});
http://jsfiddle.net/maxigs/cCawE/6/ and deep link into subitems (that did not work previously) http://fiddle.jshell.net/maxigs/cCawE/6/show/#/items/2/subitems
What changed:
root-model data moved into ApplicationRoute
root-model moved into an ember object, and sub-objects are also their own ember objects (so calling get('subitems') and other ember magic works)
changed all the controllerFor('xxx').get('model') into modelFor('xxx') (lower case!), which probably has no effect other than consistency
I'm still not sure if this is now "the ember way" of doing what i have here but its consistent and works completely as wanted.

queryFixtures always returns 0 results

I implemented queryFixtures in the FixtureAdapter to be able to make "more complex" queries. I did it like this (it's CoffeeScript):
App.Store = DS.Store.extend {
revision: 13
adapter: DS.FixtureAdapter.extend {
queryFixtures: (fixtures, query, type) ->
console.log fixtures.get('length') # 2
fixtures = fixtures.filter (item) ->
for prop of query
if item[prop] != query[prop]
return false
return true
console.log fixtures.get('length') # 1
return fixtures
}
}
Here is my Profile model + fixtures:
App.Profile = DS.Model.extend {
name: DS.attr('string')
businessName: DS.attr('string')
picture: DS.attr('string')
isBusiness: DS.attr('boolean')
conversations: DS.hasMany('App.Conversation')
}
App.Profile.FIXTURES = [
{
id: 1
name: 'Jon Snow'
picture: 'https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRDMu58ECeoIUUSMNPCEwWv4QAp4fT1fxXNK5AxK15I6GsAiBLC5Rl50zuOGQsDOedXbfE'
isBusiness: false
conversations: [101, 102]
}
{
id: 2
name: 'Jaime Lannister'
picture: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQB_K_IfaK-da-TbwgoM1NogXSc7QPVlaxaET76D8sdMoxAd1C2WCvnsKIM8-sGFpmiPPQ'
isBusiness: true
businessName: 'Westeros Inc.'
conversations: [103]
}
]
For testing purposes, I make the query on Profile in the init method of the ApplicationRoute:
App.ApplicationRoute = Ember.Route.extend {
init: ->
profiles = App.Profile.find { isBusiness: false }
console.log profiles.get('length') # 0 ??
model: ->
return App.Profile.find()
}
As you see, I logged fixtures.get('length') at different places.
The first console.log in the adapter returns "2" which is the total amout of profiles (OK).
The second console.log in the adapter returns "1" which means the filter is working (OK).
But what I don't understand is why do the third console.log in the router return "0". It's like data is not returned correctly...
I'm not sure if I'm doing it wrong, if it's a bug in Ember Data, or if it's an expected behavior. Any ideas?
FYI, here is my Ember configuration:
Ember.VERSION : 1.0.0-rc.6
Handlebars.VERSION : 1.0.0-rc.4
jQuery.VERSION : 2.0.3
The console.log outputs length 0 because fixtureAdapter is simulating an asynchronous query. To log query result size to console, use then like:
App.ApplicationRoute = Ember.Route.extend {
init: ->
profiles = App.Profile.find { isBusiness: false }
profiles.then (data) ->
console.log 'count: ', data.get('length') # 1
model: ->
return App.Profile.find()
}
JSBIN here: http://jsbin.com/utasuh/1/edit

ember Uncaught Error: assertion failed: Emptying a view in the inBuffer state

I get this assertion when run the code below:
Emptying a view in the inBuffer state is not allowed and should not
happen under normal circumstances. Most likely there is a bug in your
application. This may be due to excessive property change
notifications.
Link to demo:
http://plnkr.co/edit/s3bUw4JFrJvsL690QUMi
var App = Ember.Application.create({
Store: DS.Store.extend({
revision: 4,
adapter: DS.FixtureAdapter.create()
}),
Router: Ember.Router.extend({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: "/",
connectOutlets: function(router){
var person;
person = App.Person.find(657);
person.addObserver("isLoaded", function() {
return router.get('router.applicationController').connectOutlet("things", person.get("things"));
});
}
})
})
}),
ApplicationController: Em.Controller.extend(),
ApplicationView: Em.View.extend({
template: Em.Handlebars.compile("{{outlet}}")
}),
ThingsController: Em.ArrayController.extend({
thingTypes: (function() {
return App.ThingType.find();
}).property()
}),
ThingsView: Em.View.extend({
template: Em.Handlebars.compile([
'{{#each controller.thingTypes}}',
'{{this.name}}',
'{{/each}}',
'{{#each controller.content}}',
'{{this.title}}',
'{{/each}}'].join(""))
}),
//MODELS
Person: DS.Model.extend({
things: DS.hasMany('App.Thing', {
embedded: true
})
}),
Thing: DS.Model.extend({
description: DS.attr('string'),
thingType: DS.belongsTo("App.ThingType", {
embedded: true
}),
title: (function() {
return this.get("thingType.name");
}).property("description")
}),
ThingType: DS.Model.extend({
name: DS.attr("string")
})
});
App.Person.FIXTURES = [
{
id: 657,
things: [
{
id: 1,
description: "Some text",
thing_type: {
id: 1,
name: "type 1"
}
}, {
id: 2,
description: "Some text",
thing_type: {
id: 2,
name: "type 2"
}
}
]
}
];
App.ThingType.FIXTURES = [
{
id: 1,
name: "type 1"
}, {
id: 2,
name: "type 2"
}, {
id: 3,
name: "type 3"
}
];
Why is this happening?
I was having the same error while trying to load a list of dropdown values from fixtures. What resolved it was overriding queryFixtures on the fixture adapter:
App.FixtureAdapter = DS.FixtureAdapter.extend
latency: 200
queryFixtures: (records, query, type) ->
records.filter (record) ->
for key of query
continue unless query.hasOwnProperty(key)
value = query[key]
return false if record[key] isnt value
true
I probably wouldn't have figured it out had I not set the latency first. Then the error was a bit more descriptive.
a bit late I guess... but I got it to work here:
http://plnkr.co/edit/hDCT4Qy1h5aE6GjM76qp
Didn't change the logic but where its called
I modified your router like this:
Router: Ember.Router.extend({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: "/",
connectOutlets: function(router) {
var person;
router.set('router.applicationController.currentPerson', App.Person.find(657));
}
})
})
})
And created an ApplicationController:
ApplicationController: Em.Controller.extend({
currentPerson: null,
currentPersonLoaded: function() {
this.connectOutlet("things", this.get("currentPerson.things"));
}.observes("currentPerson.isLoaded"),
})
I dont know if this is the output you wished but the bug vanished!