Model Not Found in Ember App Kit - ember.js

I'm trying to use Ember App Kit with Ember Data (I'm using the latest of Both) using Fixtures - but for some reason I'm getting the following:
Assertion failed: No model was found for 'todo' [VM] ember.js (4005):415
Error while loading route: TypeError {} [VM] ember.js (4005):415
Uncaught TypeError: Cannot set property 'store' of undefined ember-data.js:2182
Application
import Resolver from 'resolver';
import registerComponents from 'appkit/utils/register_components';
var App = Ember.Application.extend({
LOG_ACTIVE_GENERATION: true,
LOG_MODULE_RESOLVER: true,
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true,
LOG_VIEW_LOOKUPS: true,
modulePrefix: 'appkit', // TODO: loaded via config
Resolver: Resolver
});
App.initializer({
name: 'Register Components',
initialize: function(container, application) {
registerComponents(container);
}
});
App.ApplicationAdapter = DS.FixtureAdapter.extend();
export default App;
Index Route
import Todo from 'appkit/models/Todo';
var IndexRoute = Ember.Route.extend({
model: function() {
return this.store.findAll('todo');
}
});
export default IndexRoute;
Todo Model
var Todo = DS.Model.extend({
'title': DS.attr('string'),
'user': DS.attr('object'),
'comment': DS.attr('string'),
'mood': DS.attr('string')
});
Todo.FIXTURES = [{
'title': 'Received Hardware!',
'user': { 'username': 'alvincrespo' },
'comment': 'Finally received my hardware!',
'mood': 'happy'
}, {
'title': 'This is honorable.',
'user': { 'username': 'robwolf' },
'comment': 'I regret it already.',
'mood': 'happy'
}, {
'title': 'I can\'t seem to speak',
'user': { 'username': 'catstark' },
'comment': 'Wait a minute, why am I hear?',
'mood': 'sad'
}, {
'title': 'Attendance is poor.',
'user': { 'username': 'cerlan' },
'comment': 'Kings landing seems pretty empty after the war.',
'mood': 'neutral'
}];
export default Todo;
I've declared the DS.FixtureAdapter in app.js but for some reason its still not working? Any ideas?
Thanks!

I'm not positive about what the register components pieces does. But essentially it's saying it doesn't know about the Todo Model (generally it find it by looking for model's described in its namespace, aka App.Todo = DS.Model.extend....)
You might also need to still declare the store.
App.Store = DS.Store.extend();
And in Ember Data 1.0 beta 1 you do the adapter like so
App.ApplicationAdapter = DS.MyRESTAdapter; // note you don't extend/create it

Related

Ember: working with http-mock and improper JSON

Trying to work with http-mock feature of Ember-cli. My plan is not input some improper JSON(without root model, no Ids, embedded model instead of side loaded model etc etc) . Since i am new to this i first tried setting up a mock server with proper data and it was successful. Below is the relevant code.
adapters/post.js
import DS from "ember-data";
export default DS.RESTAdapter.extend({
namespace: 'api',
});
pods/post/route.js
import Ember from "ember";
export default Ember.Route.extend({
model: function(){
return this.store.find('post');
}
});
models/post.js
import DS from 'ember-data';
export default DS.Model.extend({
author: DS.attr('string'),
title: DS.attr('string'),
body: DS.attr('string'),
comments: DS.hasMany('comments')
});
server/mocks/posts.js
module.exports = function(app) {
var express = require('express');
var postsRouter = express.Router();
postsRouter.get('/', function(req, res) {
res.send({
"posts" : [{
'id': 1,
'author': 'Brian',
'title': 'Ember JS',
'body': 'JS framework for creating ambitious web applications',
'comments': [11,12]
}]
});
});
app.use('/api/posts', postsRouter);
};
This this point everything works fine. The above mock server data relates to the below JSON from an API call
{
"posts" : [{
'id': 1,
'author': 'Brian',
'title': 'Ember JS',
'body': 'JS framework for creating ambitious web applications',
'comments': [11,12]
}]
}
How would i write my mock-server code to produce a JSON which looks like this without root model?
{
'id': 1,
'author': 'Brian',
'title': 'Ember JS',
'body': 'JS framework for creating ambitious web applications',
'comments': [11,12]
}
Sorry for the long post and thanks in advance.
-Anees
Actually figured out a way myself and turned out to be quite easy.
server/mocks/posts.js
module.exports = function(app) {
var express = require('express');
var postsRouter = express.Router();
postsRouter.get('/', function(req, res) {
res.send(
{
'id': 1,
'author': 'Brian',
'title': 'Ember JS',
'body': 'JS framework for creating ambitious web applications',
'comments': [{
'author': 'Jimmy',
'body': 'Its cool',
},
{
'author': 'Jake',
'body': 'steep learning curve'
}]
}
);
});
app.use('/api/posts', postsRouter);
};
So basically its as simple as putting your desired JSON inside
res.send(
);
Thanks

Ember Data - how to findBy with an associated hasMany

I have two objects User and Post. A user has many posts and a post belongs to a user.
How do I, within the user controller, use findBy or another method to get to a featured post with the posts array??
Here is how I implemented the UserController; however, the featuredPost computed property is coming back as undefined. Is this best approach? If so, what am I missing?
App.User = DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string'),
client: DS.belongsTo('App.Client', { async: true }),
posts: DS.hasMany('App.Post', { async: true })
});
App.Post = DS.Model.extend({
client: DS.belongsTo('App.Client', { async: true }),
user: DS.belongsTo('App.User', { async: true }),
title: DS.attr('string'),
body: DS.attr('string'),
isFeatured: DS.attr('boolean')
});
App.UserController = Ember.ObjectController.extend({
needs: ['post'],
posts: (function() {
return Ember.ArrayProxy.createWithMixins(Ember.SortableMixin, {
content: this.get('content.posts')
});
}).property('content.posts'),
featuredPost: (function() {
return this.get('content.posts').findBy('isFeatured', true)
}).property('content.featuredPost'),
});
Take a look at this: http://emberjs.com/api/#method_computed_filterBy
App.UserController = Ember.ObjectController.extend({
featuredPost: Ember.computed.filterBy('posts', 'isFeatured', true)
});
Also, in
featuredPost: (function() {
return this.get('content.posts').findBy('isFeatured', true);
}).property('content.featuredPost')//should be observing 'posts'
You are basically observing content.featuredPost but from what youve mentioned that property doesnt exist, the property you should be observing is 'posts'. This is a mistake that i made when i was learning ember too, so felt like pointing out. Also using content is optional, you can directly observe the model associated with controller.
Also From doc, findBy seems to return just first item that matches the passed value, not all of them. So to get first match it should be
App.UserController = Ember.ObjectController.extend({
featuredPost: function() {
return this.get('posts').findBy('isFeatured', true);
}.property('posts')//assuming user model hasMany relation to posts
});
Also I would go with the latest version of ember data and make following changes:
App.User = DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string'),
client: DS.belongsTo('client', { async: true }),
posts: DS.hasMany('post', { async: true })
});
App.Post = DS.Model.extend({
client: DS.belongsTo('client', { async: true }),
user: DS.belongsTo('user', { async: true }),
title: DS.attr('string'),
body: DS.attr('string'),
isFeatured: DS.attr('boolean')
});
This would be good read : https://github.com/emberjs/data/blob/master/TRANSITION.md
And here is a bare minimum working example : http://jsbin.com/disimilu/5/edit
Hope this helps.

Ember DS.Store error while submitting form

I'm a newbie to ember and I'm trying to create a basic sign-up form.
Relevant model:
App.NewUser = DS.Model.extend({
user_name: DS.attr('string'),
password: DS.attr('string'),
confirm_password: DS.attr('string'),
email: DS.attr('string'),
first_name: DS.attr('string'),
last_name: DS.attr('string'),
});
Relevant controller:
App.SignupController = Ember.ArrayController.extend({
actions: {
signup: function() {
var data = this.getProperties('first_name', 'last_name', 'email', 'user_name', 'password', 'confirm_password');
var newUser = this.store.createRecord('newUser', data);
newUser.save();
},
},
});
When the "signup" action executes, I get the following error:
Error: Attempted to handle event `didSetProperty` on <App.NewUser:ember332:null> while in state root.deleted.saved. Called with {name: last_name, oldValue: undefined, originalValue: undefined, value: undefined}.
What am I doing wrong?
This is a bug, Ember Data is setting the record state incorrectly if you're setting a value to what it's currently set to (undefined on createRecord)
You'll want to either coerce your values into empty strings or not set undefined values while creating the record.
for(var key in data){
if(!data[key]) delete data[key];
}
http://emberjs.jsbin.com/OxIDiVU/124/edit
https://github.com/emberjs/data/issues/1648

Ember data alias model / Map JSON response

My server returns a JSON response like this:
{
artists: [{
id: "1",
first_name: "Foo",
last_name: "Bar"
}],
studios: [{
id: 1,
name: "Test",
// ...
artist_ids: ["1"]
}]
}
'artist' is in fact a User model but with a different name. How can I map artist to the User model? Maybe a bad explanation but if I rename the JSON response serverside to 'users' instead of 'artist' and use the models below everything works like I want. I simply want to use the name 'artist' instead of 'user', both server side and client side. Hope you guys understand what i mean.
App.Studio = DS.Model.extend
name: DS.attr 'string'
// ..
users: DS.hasMany 'App.User'
App.User = DS.Model.extend
firstName: DS.attr 'string'
lastName: DS.attr 'string'
studio: DS.belongsTo 'App.Studio'
I guess that the simplest thing to do would be something like artists: DS.hasMany 'App.User' but obviously this does not work.
First, I recommend using the latest Ember / EmberData, so relationships are defined like this:
App.Studio = DS.Model.extend({
name: DS.attr('string'),
// ..
users: DS.hasMany('user')
});
App.User = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
studio: DS.belongsTo('studio')
});
Next, I recommend using the ActiveModelAdapter if you are getting underscores in your response JSON:
App.ApplicationAdapter = DS.ActiveModelAdapter;
Finally, overriding typeForRoot and keyForRelationship in a custom serializer should fix your issue:
App.ApplicationSerializer = DS.ActiveModelSerializer.extend({
typeForRoot: function(root) {
if (root == 'artist' || root == 'artists') { root = 'user'; }
return this._super(root);
},
keyForRelationship: function(key, kind) {
if (key == 'users') { key = 'artists'; }
return this._super(key, kind);
}
});
Example JSBin
One last thing: you can even get rid of the custom keyForRelationship if you name the relationship artists in Studio:
App.Studio = DS.Model.extend({
name: DS.attr('string'),
// ..
artists: DS.hasMany('user')
});
Have you tried just creating an Artist model extended from User?
App.Artist = App.User.extend({})
I haven't tried it, but I suspect that might work.

Create an associated model from JSON

I have a server response that looks like:
comments: [
0: {
body: "test3",
created_at: "2013-06-27T22:27:47Z",
user: {
email: "test#test.com",
id: 1,
name: "Tester"
}
}
]
And ember models:
App.Comment = DS.Model.extend({
user: DS.belongsTo('App.User'),
body: DS.attr('string')
});
App.User = DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string'),
});
How do I create an ember user model from the server's response?
The solution if you're using rails active model serializers is to embed :ids, include: true:
app/serializers/comment_serializer.rb
class CommentSerializer < ActiveModel::Serializer
embed :ids, include: true
attributes :created_at, :body
has_one :user
end
Just like the readme for active_model_serializers says, this will produce:
{
"users":[
{
"id":1,
"name":"Tester",
"email":"test#test.com",
}
],
"comments":[
{
"event":"commented",
"created_at":"2013-06-27T22:27:47Z",
"body":"test3",
"user_id":1
}
]
}