Ember Starter Kit with Ember Data - ember.js

Ember 1.0.0 RC3 ships with a Starter Kit with quite a simplistic demo to display three colors in a list.
The model data is inserted directly on the IndexRoute like this:
App.IndexRoute = Ember.Route.extend({
model: function() {
return ['red', 'yellow', 'blue'];
}
});
I tried to change this simple demo to use ember-data (Models, Store, ...). However, with no success. The console output of my demo is:
DEBUG: ------------------------------- ember-1.0.0-rc.3.js:349
DEBUG: Ember.VERSION : 1.0.0-rc.3 ember-1.0.0-rc.3.js:349
DEBUG: Handlebars.VERSION : 1.0.0-rc.3 ember-1.0.0-rc.3.js:349
DEBUG: jQuery.VERSION : 1.9.1 ember-1.0.0-rc.3.js:349
DEBUG: ------------------------------- ember-1.0.0-rc.3.js:349
Uncaught TypeError: Cannot call method 'find' of undefined appDemo.js:8
Uncaught Error: assertion failed: an Ember.CollectionView's content must implement Ember.Array. You passed <(generated index controller):ember232> ember-1.0.0-rc.3.js:52
My modified script looks like this:
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: App.Color.find()
});
App.ColorsController = Ember.ArrayController.extend();
// Models
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.FixtureAdapter'
});
App.Color = DS.Model.extend({
name: DS.attr('string')
});
App.Color.FIXTURES = [{name: 1}, {name: 2}, {name: 3}, {name: 4}, {name: 5}, {name: 6}];
My html looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each color in controller}}
<li>{{color.name}}</li>
{{/each}}
</ul>
</script>
<script src="js/libs/jquery-1.9.1.js"></script>
<script src="js/libs/handlebars-1.0.0-rc.3.js"></script>
<script src="js/libs/ember-1.0.0-rc.3.js"></script>
<script src="js/libs/ember-data-latest.js"></script>
<script src="js/appDemo.js"></script>
</body>
</html>
What am I doing wrong?

First error lies in
App.IndexRoute = Ember.Route.extend({
model: App.Color.find()
});
You must define the model option as a function like:
App.IndexRoute = Ember.Route.extend({
model: function() {
return App.Color.find();
}
});
The second error I'm a little uncertain on but try this out first.

Related

Ember data this.store getting undefine

I want to add new record to store using emberdata.Js but not working
Here is my code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="ED: Reading" />
<script src="js/jquery-1.10.2.js"></script>
<script src="js/handlebars-1.1.2.js"></script>
<script src="js/ember-1.5.1.js"></script>
<script src="http://builds.emberjs.com/beta/ember-data.prod.js"></script>
<script type="text/javascript">
App = Ember.Application.create();
App.Store = DS.Store.extend({
revision: 12,
url: 'http://localhost/Ember/Demo2/'
});
App.Pull = DS.Model.extend({
title: DS.attr(),
url: DS.attr(),
});
App.Router.map(function(){
this.resource('pull');
});
var store = this.store;
//var obj = App.Pull.createRecord();
App.PullRoute = Ember.Route.extend({
model:
function() {
store.createRecord('pull', {
title: 'Rails is Omakase',
url: 'Lorem ipsum'
});
//return this.store.find('pull');
//return App.Pull.find();
//this.store.createobjects(response);
}
});
</script>
</head>
<body>
<script type="text/x-handlebars">
<h1>Welcome</h1>
<div class="navbar-header">
{{#link-to 'pull' classNames='navbar-brand'}}
City List
{{/link-to}}
</div>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="pull">
<h2>GetAllCityList</h2>
<div class="navbar-header">
<ul>
{{#each model}}
<li>{{title}}</li>
{{/each}}
</ul>
</div>
</script>
</body>
</html>
I am trying to add record to store type of model on calling of model city but this.store is giving me undefined.
below is error in ember insepctor
Error while loading route: TypeError: Cannot read property 'createRecord' of undefined
at App.PullRoute.Ember.Route.extend.model (http://localhost/Ember/Demo2/storedemo.html:42:9)
at superWrapper [as model] (http://localhost/Ember/Demo2/js/ember-1.5.1.js:1292:16)
at Ember.Route.Ember.Object.extend.deserialize (http://localhost/Ember/Demo2/js/ember-1.5.1.js:36570:19)
at http://localhost/Ember/Demo2/js/ember-1.5.1.js:32972:57
at http://localhost/Ember/Demo2/js/ember-1.5.1.js:33464:19
at invokeResolver (http://localhost/Ember/Demo2/js/ember-1.5.1.js:9646:9)
at new Promise (http://localhost/Ember/Demo2/js/ember-1.5.1.js:9632:9)
at Router.async (http://localhost/Ember/Demo2/js/ember-1.5.1.js:33463:16)
at Object.HandlerInfo.runSharedModelHook (http://localhost/Ember/Demo2/js/ember-1.5.1.js:32971:16)
at Object.UnresolvedHandlerInfoByParam.getModel (http://localhost/Ember/Demo2/js/ember-1.5.1.js:33058:19)
>this.store
undefined
Just FYI From Ember models docs:
"The store object is available in controllers and routes using this.store"
I was running into this error because I was attempting to access the store from a component.js file.
Really helpful article on this problem from Josh Farrant here
You might use following way to create your record:
...
var obj = store.createRecord('pull', {
title: 'Rails is Omakase',
url: 'Lorem ipsum'
});
obj.save().then(function(record){
return record;
});
Looks like a scoping issue. You're assigning 'var store = this.store;' in the scope of your application, but Ember.js creates new objects based on your extended definition of Ember.Route and so the scope for 'store' in App.PullRoute may be different than it appears.
Try this:
App.PullRoute = Ember.Route.extend({
model: function() {
this.store.createRecord('pull', {
title: 'Rails is Omakase',
url: 'Lorem ipsum'
});
}
});
I don't see any issue. I did get the store returned when i tried it. I just created a jsbin in case you might want to check.
http://emberjs.jsbin.com/zesemuqe/1/edit
I did find two issues. 1. You sure are trying to create a record which gets it into the store. But you are not returning it.
App.PullRoute = Ember.Route.extend({
model: function() {
return this.store.createRecord('pull', {
title: 'Rails is Omakase',
url: 'Lorem ipsum'
});
}
});
2.Secondly, I can see that you are trying to loop over the model which is not an array and just an object, so handlebars does throw an error on that.
<script type="text/x-handlebars" data-template-name="pull">
<ul>
<li>{{title}}</li>
</ul>
</script>
And I know it surely isn't the issue, but did you load all the dependencies correctly, the jsbin is missing them ?

ember doesn't access to websocketAdapter

I'm new with ember and i'm trying to do a websocket that receives JSON data from my golang Server in real time , The problem with my code is that it doesn't seem to be reading the adapter that i have created and so my socket doesn't connect to the server. I think that my code is missing something in application.js or index.html that will allow me to access to my adapter and use its methods!
this is my application.js:
App = Ember.Application.create({
LOG_TRANSITIONS: true
})
/******************************* Post Template **************************************/
//Define a route for the template "post"
App.Router.map(function() {
this.route("post", { path: "/post" });
});
App.PostsRoute = Ember.Route.extend({
model: function() {
return this.store.find("posts");
console.log(post);
}
})
//Post Model
App.Post = DS.Model.extend({
name: DS.attr('string'),
number: DS.attr('string')
});
/**************************** websocket mixin ************************************/
App.WebSocketHandler = Ember.Object.extend({
uri: 'ws://localhost:8081/',
//ws: undefined
initialize: function() {
// this.ws = new WebSocket(this.uri);
var ws = new WebSocket(uri);
// callbacks
this.ws.onopen = function() {
console.log('Connection established /all');
};
this.ws.onclone = function() {
console.log('Connection closed /' + 'all');
};
this.ws.onmessage = function(data) {
DS.get('defaultStore').load(App.Post, data); //Simply load your json in the store.
};
this._super();
}
});
/************************* websocket Adapter ********************************************/
DS.SocketAdapter = DS.RESTAdapter.extend({
socket: undefined,
init: function(){
this.socket = new App.WebSocketHandler();
this._super();
},
find: function (store, type, id) {
// empty block
console.log('find');
},
findAll: function (store, type) {
// empty block
console.log('findAll');
},
createRecord: function(store, type, record) {
// code not relevant
console.log('createRecord');
}
});
App.ApplicationAdapter = DS.SocketAdapter;
// Use the adapter in the store
App.Store = DS.Store.extend({
revision: 12,
adapter: 'SocketAdapter'
});
and my index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Ember.js Example Application</title>
<script src="js/libs/jquery-1.10.2.js"></script>
<script src="js/libs/handlebars-1.1.2.js"></script>
<script src="js/libs/ember-1.5.1.js"></script>
<script src="js/libs/Ember_Data.js"></script>
<script src="js/application.js"></script>
<script src="js/router.js"></script>
<script src="js/models/model.js"></script>
</head>
<body>
<h1>Bonjour </h1>
<script type="text/x-handlebars">
Hello, {{firstName}} {{lastName}}<br/>
<nav>
{{#link-to 'post'}}Post{{/link-to}}
</nav>
<div>
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="index">
<h2>My Wrappers</h2>
<ul>
{{#each post in model}}
<li>{{post.number}}</li>
{{/each}}
</ul>
</script></p>
<script type="text/x-handlebars" data-template-name="post">
<ul>
{{#each post in model}}
<li>Wrapper Name: {{post.name}}</li>
<li>Wrapper Number: {{post.number}}</li>
{{/each}}
</ul>
</script>
<script type="text/javascript">
</script>
</head>
<body>
</body>
</html>
You have some errors in your code.
1) Ember Object uses its own create method.
this.socket = new App.WebSocketHandler();
// change to
this.socket = App.WebSocketHandler.create({});
2) Your route and route template was not correctly named to posts.
this.route("posts", { path: "/posts" });
http://emberjs.jsbin.com/qixur/1/edit

Ember Data Beta 2 FixtureAdapter Errors

I'm assuming that the API has changed for how to use adapters but I couldn't find any examples using the fixture adapter. I'm using the new injected store but not sure how to interact with it. I'm just trying to fetch all of the data. Here is a fiddle http://emberjs.jsbin.com/ESoduyA/1/edit.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="https://rawgithub.com/emberjs/starter-kit/v1.0.0/css/normalize.css">
</head>
<body>
<script type="text/x-handlebars">
<h2>Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<ul>
{{#each item in model}}
<li>{{item.type}}</li>
{{/each}}
</ul>
</script>
<script src="https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/jquery-1.9.1.js"></script>
<script src="https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/handlebars-1.0.0.js"></script>
<script src="https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js"></script>
<script src="http://builds.emberjs.com/beta/ember-data.js"></script>
</body>
</html>
JS
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.get('store').findAll('color');
}
});
App.store = DS.Store.create({
adapter: 'DS.FixtureAdapter'
});
App.Color = DS.Model.extend({
type: DS.attr()
});
App.Color.FIXTURES = [
{type: 'blue'},
{type: 'green'}
];
This results in these errors.
Assertion failed: No model was found for 'html' ember-1.0.0.js:394
DEPRECATION: Action handlers contained in an `events` object are deprecated in favor of putting them in an `actions` object (error on <Ember.Route:ember245>)
at Object.triggerEvent (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:30519:13)
at trigger (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:29641:16)
at handleError (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:29903:9)
at invokeCallback (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:8055:19)
at null.<anonymous> (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:8109:11)
at EventTarget.trigger (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:7878:22)
at https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:8180:17
at Object.DeferredActionQueues.flush (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:5459:24)
at Object.Backburner.end (https://rawgithub.com/emberjs/starter-kit/v1.0.0/js/libs/ember-1.0.0.js:5545:27) ember-1.0.0.js:394
Error while loading route:
TypeError
ember-1.0.0.js:394
Uncaught TypeError: Cannot set property 'store' of undefined
Here's some info on the FixtureAdapter. http://emberjs.com/guides/getting-started/using-fixtures/
tl,dr :
App.ApplicationAdapter = DS.FixtureAdapter.extend();
App.Color.FIXTURES = [
{id: 1, type: 'blue'},
{id: 2, type: 'green'}
];
Tweaked bin : http://emberjs.jsbin.com/ESoduyA/4/edit

rendering a template with multiple outlets

I was trying to render out some content n the named outlets with no success. I tried following How to render multiple templates for a route in Router v2 but the solution there is not working for me!
My html page looks like:`
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<!-- Set the viewport width to device width for mobile -->
<meta name="viewport" content="width=device-width" />
<title>Demo</title>
<style>
.main-container{
width:800px;
margin:0px auto;
}
</style>
</head>
<body>
<script type="text/x-handlebars" data-template-name="application">
<div class="main-container">
<div>{{outlet topMenu}}</div>
<div>
<div style="float:left; width:30%;">{{outlet sideMenu}}</div>
<div style="float:left; width:70%;">{{outlet content}}</div>
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="menu">
<ul>
{{#each model}}
<li>{{label}}</li>
{{/each}}
</ul>
</script>
<script src="../js/ember/libs/jquery-1.9.1.js"></script>
<script src="../js/ember/libs/handlebars-1.0.0-rc.4.js"></script>
<script src="../js/ember/libs/ember-1.0.0-rc.6.1.js"></script>
<script src="../js/ember/libs/ember-data-master.js"></script>
<script src="../js/ember/demo.js"></script>
</body>
</html>
At the moment I don't even want to bother about the sideMenu and content, I just wanted to get the top menu showing up to start with.The corresponding js is:
window.App = Ember.Application.create();
// Router
App.Router.map(function() {
this.resource('menu',{ path: "/" },function(){
this.resource('sideMenu',{ path: "/:menu_id" },function(){
this.resource('content',{path:'/content/:content_id'});
});
});
});
App.IndexRoute = Ember.Route.extend({
renderTemplate: function() {
this.render('menu',{outlet:'topMenu',controller:this.controllerFor('menu', App.Menu.find())});
}
});
App.MenuRoute = Ember.Route.extend({
model:function(){
return App.Menu.find();
}
});
App.Store = DS.Store.extend({
revision:12,
adapter:'DS.FixtureAdapter'
//adapter:DS.RESTAdapter.extend({
// url: 'http://....'
//})
});
App.Menu = DS.Model.extend({
label: DS.attr('string')
,subMenu: DS.hasMany('App.subMenu')
});
App.SubMenu = DS.Model.extend({
label: DS.attr('string')
,content :DS.attr('string')
});
App.SubMenu.FIXTURES = [
{
id:1
,label:"Sub1"
,content:'Hello there 1'
}
,{
id:2
,label:"Sub2"
,content:'Hello there 2'
},{
id:3
,label:"Sub3"
,content:'Hello there 3'
},{
id:4
,label:"Sub4"
,content:'Hello there 4'
}
];
App.Menu.FIXTURES = [
{
id:1,
label:"Home",
subMenu:[1,2]
},
{
id:2,
label:"Api",
subMenu:[3,4]
}
];`
I am not sure if my router is set up in-correctly. Any feedback would be highly appreciated.
Regards,
Dee
I'm guessing that IndexRoute is not being used by ember. Probably what you want instead is to use MenuIndex:
App.MenuIndexRoute = Ember.Route.extend({
renderTemplate: function() {
this.render('menu',{outlet:'topMenu',controller:this.controllerFor('menu', App.Menu.find())});
}
});
Try turning on logging so that you can see which routes/controllers/views/templates are being used by ember:
var App = Ember.Application.create({
LOG_VIEW_LOOKUPS: true,
LOG_ACTIVE_GENERATION: true
});
http://blog.emberwatch.com/2013/06/13/logging-the-magic-in-ember-js.html

How to render hasMany relationship data?

How can I get the following example code to render not just the person data but also the phone numbers of that person when rendering the URL /#/persons/1. I try to loop though the phone numbers with {{#each phoneNumber in phoneNumbers}} but there has to be a fundamental understanding error on my side.
Right now I only get:
app.js
App = Ember.Application.create({
LOG_TRANSITIONS: true,
rootElement: '#container'
});
// Router
App.Router.map(function() {
this.resource('persons', function() {
this.resource('person', { path: ':person_id' });
});
this.resource('phoneNumbers', function() {
this.resource('phoneNumber', { path: ':phone_number_id' });
});
});
App.PersonsRoute = Ember.Route.extend({
model: function() {
return App.Person.find();
}
});
App.PhoneNumbersRoute = Ember.Route.extend({
model: function() {
return App.PhoneNumber.find();
}
});
// Models
App.Store = DS.Store.extend({
revision: 11,
adapter: 'DS.FixtureAdapter'
});
App.Person = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
phoneNumbers: DS.hasMany('App.PhoneNumber')
});
App.PhoneNumber = DS.Model.extend({
number: DS.attr('string'),
person: DS.belongsTo('App.Person')
});
App.Person.FIXTURES = [{
id: 1,
firstName: 'X',
lastName: 'Smith'
}, {
id: 2,
firstName: 'Y',
lastName: 'Smith'
}];
App.PhoneNumber.FIXTURES = [{
id: 1,
person_id: 1,
number: '20'
}, {
id: 2,
person_id: 1,
number: '23'
}, {
id: 3,
person_id: 2,
number: '42'
}];
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Phone book</title>
</head>
<body>
<div id='container'></div>
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="persons">
<p>All people:</p>
<ul>
{{#each controller}}
<li>{{firstName}} {{lastName}}</li>
{{/each}}
</ul>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="person">
<h1>{{firstName}} {{lastName}}</h1>
{{#if phoneNumbers.length}}
<ul>
{{#each phoneNumber in phoneNumbers}}
<li>{{phoneNumber.number}}</li>
{{/each}}
</ul>
{{/if}}
</script>
<script type="text/x-handlebars" data-template-name="phone_numbers">
<ul>
{{#each controller}}
<li>{{number}}</li>
{{/each}}
</ul>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="phone_number">
<h1>{{number}}</h1>
</script>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="js/handlebars.js"></script>
<script type="text/javascript" src="js/ember.js"></script>
<script type="text/javascript" src="js/ember-data.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</html>
Ember-data doesn't act like ActiveRecord in this regard: when you use has_many you have to have a property that is an array of ids for the records. It isn't enough to have a foreign key for the owner on the reciprocal model.
try adding phoneNumbers: [1, 2] to your first Person fixture, and phoneNumbers: [3] to the second.
If you were using the RESTAdapter, those key names would be phone_number_ids instead. If you use active_model_serializers you can use the embed feature to automatically include an array of ids.