Problems retrieving data from controller using Ember.js 2.3.0 - ember.js

I am trying to learn ember following this course and I have the following controller
import Ember from 'ember';
export default Ember.Controller.extend({
title:'My Blog Post',
body:'Body of the post',
authors:['Author1', 'Author2', 'Author3'],
comments:[
{
name:'name 1',
comment:'comment 1'
},
{
name:'name 2',
comment:'comment 2'
},
{
name:'name 3',
comment:'comment 3'
}
]
});
And Template:
<h1>{{title}}</h1>
<p>{{body}}</p>
<p>
<strong>Authors:</strong>
{{#each authors}}
{{this}},
{{/each}}
</p>
<h4>Comments</h4>
<ul>
{{#each comments as c}}
<li><strong>{{name}}</strong> - {{comment}}</li>
{{/each}}
</ul>
And it has been generating this output:
My Blog Post
Body of the post
Authors: <my-app#controller:post::ember424>, <my-app#controller:post::ember424>, <my-app#controller:post::ember424>,
Comments
-
-
-
I double check everything and it is identical to the demo I am seem, I also try to use {{#each comments as |c|}}, {{each authors as author}} {{this.author}}, try to use {{c.name}}, also try {{this.name}}, {{this.c.name}}
Any ideas where I am going wrong?
Thanks in advance

Change your template file to this:
<h1>{{title}}</h1>
<p>{{body}}</p>
<p>
<strong>Authors:</strong>
{{#each authors as |author|}}
{{author}},
{{/each}}
</p>
<h4>Comments</h4>
<ul>
{{#each comments as |c|}}
<li><strong>{{c.name}}</strong> - {{c.comment}}</li>
{{/each}}
</ul>

Related

Binding class from an array in Ember.js

I'm starting with Ember.js and I'm feeling a bit lost.
I have an object like this:
App.BRANDS = [
{
brand:'Audi'
},{
brand:'BMW'
},{
brand:'Skoda'
}];
So what I'm trying is to display all the elements in that object with the {{#each}} component, show the text inside and bind the same text as a className. So I code this in the route:
App.InsuranceAutoSelectBrandRoute = App.Route.extend({
model: function(){
return App.BRANDS;
}
});
And this in the template:
<article>
{{#each brand in model tagName='ul'}}
<li class='item-space'>
<span {{bind-attr class=':brand-auto classNameAuto'}}></span>
{{brand.brand}}
</li>
{{/each}}
</article>
Then the issue is that the name of each brand, before I bind it as a class attr I have to lowercase it...
App.InsuranceAutoSelectBrandController = Ember.Controller.extend({
classNameAuto: function() {
App.BRANDS.forEach(function(item, index){
return item.brand.toLowerCase();
});
}.property()
});
If in the same point where I'm returning the value I make a log, it works, but the class attr is not showing.
What I'd like:
<article>
<li class='item-space'>
<span class='brand-auto audi'}}></span>
Audi
</li>
<li class='item-space'>
<span class='brand-auto bmw'}}></span>
BMW
</li>
<li class='item-space'>
<span class='brand-auto skoda'}}></span>
Skoda
</li>
</article>
Forgive me for my English level and thank you
First, as #Kitler said, bind-attr is deprecated. If you are using 1.13.x or higher, you may just insert class as any other variable, {{brand.brand}}.
Second, your code is incorrect and will not work. The easiest way to do what you want is via helper. You need to create a helper, lower-case and use it in this way:
<article>
<ul>
{{#each model as |brand|}}
<li class='item-space'>
<span class='brand-auto {{lower-case brand.brand}}'>{{brand.brand}}</span>
</li>
{{/each}}
</ul>
</article>
How to create a helper you may learn from documentation (http://guides.emberjs.com/v1.13.0/templates/writing-helpers/). If you use ember-cli, following code should work:
//app/helpers/lower-case.js
import Ember from 'ember';
export default Ember.Handlebars.makeBoundHelper(function (str) {
return str.toLowerCase();
});

Is there itemController for new each syntax in Ember?

The new syntax
{{#each pages as |page| itemController="listedPage"}}
causes parse error. Is item Controller usable with the new "each" syntax?
If yes, how to specify it? If not, what is the preferred way to use computed properties with the items of "each"?
Controllers are being phased out - so I would recommend using components..
Component for Each Item
You could implement a 'listed-page' component which would look something like this:
Your template:
<ul>
{{#each pages as |page|}}
{{listed-page page=page}}
{{/each}}
</ul>
The component:
## components/listed-page.js
export default Ember.Component.extend({
tagName: 'li',
page: null,
pageNumberFancy: function() {
return '^'+this.get('page.number')+'^';
}.property('page.number')
})
## templates/components/listed-page.hbs
Number: {{page.number}} ({{pageNumberFancy}})
The output:
<div class='template-level'>
<ul class='template-level'>
<li class='listed-page-level'>Number: 1 (^1^)</li>
<li class='listed-page-level'>Number: 2 (^2^)</li>
</ul>
</div>
Component for the List
Or a listed-pages component - if 'pages' is an array computed property - or both:
Your template:
{{listed-pages pages=pages}}
The component:
## components/listed-pages.js
export default Ember.Component.extend({
tagName: 'ul',
pages: null,
pagesPlusOne: function() {
var pagesList = this.get('pages');
pagesList.addObject(specialPage);
return pagesList;
}.property('pages.[]')
})
## templates/components/listed-pages.hbs
{{#each pagesPlusOne as |page|}}
{{listed-page page=page}}
{{/each}}
The output:
<div class='template-level'>
<ul class='listed-pages-level'>
<li class='listed-page-level'>Number: 1 (^1^)</li>
<li class='listed-page-level'>Number: 2 (^2^)</li>
<li class='listed-page-level'>Number: +1 (^+1^)</li>
</ul>
</div>

Use {{yield}} inside {{each}} in Ember.Component

Is there a way to use {{yield}} inside a {{each}} helper in a Ember.Component?
So I can provide a repating structure with a component, and maybe a add/remove line functionality, but I can provive handlebars markup from outside and use the {{yield}} helper to access that.
Thats what I wanna do:
items:
[{
name: 'stack',
value: 5
}, {
name: 'overflow',
value: 8
}]
template:
{{#show-list value=items}}
{{name}} - {{value}}
{{/show-list}}
component:
<ul>
{{#each value}}
<li>{{yield}}</li>
{{/each}}
</ul>
And thats what I expect back:
<ul>
<li>stack - 5</li>
<li>overflow - 8</li>
</ul>
This is now possible in Ember using public APIs.
See this twitter post from Yehuda:
https://twitter.com/wycats/status/536723973745410048
And this demo:
http://jsbin.com/yawasisofu/4/edit?html,js,output
In your case, the component should look like:
<ul>
{{#each value as listItem}}
<li>{{yield listItem}}</li>
{{/each}}
</ul>

Ember - partial template with fixture data

I just started with Ember and have a basic web app structure in place. I have a partial template set up and want to bring some test data into it. I can see my test data if I use my 'home' template for it, but I can not get it into my collections partial template. I'm almost certain it has to be related to basic Ember concepts that I have no familiarity with. Here is my simplified html and below is the Ember js. If anybody has any idea how I could bring the 'each' loop from 'home' template into my partial 'collections' template, I'll be very thankful:
[code]
<script type="text/x-handlebars" ><!-- data-template-name="application" -->
<div id="main">
<ul>
<li>
<image src="logo.png" style="width:439px;height:102px;"/>
</li>
<li>{{#link-to 'home'}}Home{{/link-to}} | {{#link-to 'help'}}Help{{/link-to}}</li>
</ul>
</div>
<div class="collections">
{{partial 'collections'}}
</div>
<div class="statistics">
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" id="collections">
COLLECTIONS<br/>
<!-- here is where I wand the 'each' loop to go -->
</script>
<script type="text/x-handlebars" id="home">
OnLoad : This is Home Page<br/>
<ul>
{{#each}}
<li>
<label>{{title}}</label>
</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" id="help">
Welcome to Help Page
</script>
[/code]
And here is JS code for the above:
[code]
App = Ember.Application.create();
App.Router.map(function(){
this.resource('home', { path: '/' });
this.resource('help');
});
App.CollectionsRoute = Ember.Route.extend({
model: function(){
return items;
}
});
App.HomeRoute = Ember.Route.extend({
model: function(){
return items;
}
});
var items = [
{
id: 1,
title: 'Item 1',
belongsTo: 'parent path 1'
},{
id: 2,
title: 'Item 2',
belongsTo: 'parent path 2'
},{
id: 3,
title: 'Item 3',
belongsTo: 'parent path 3'
}
];
[/code]
partial 'collections' have the same context of application template. So if you declare:
App.ApplicationRoute = Ember.Route.extend({
model: function(){
return items;
}
});
Will be able to use:
<script type="text/x-handlebars" id="collections">
COLLECTIONS<br/>
<ul>
{{#each}}
<li>
<label>{{title}}</label>
</li>
{{/each}}
</ul>
</script>

How to render hasMany associations each with their own controller

So my models are set up like this :
App.Post = DS.Model.extend
comments: DS.hasMany 'App.Comment'
App.Comment = DS.Model.extend
post: DS.belongsTo 'App.Post'
I'm trying to create a view that has all posts and all comments display, but I need to decorate the comment objects.
This is what I'd like to do but, to no avail :
<ul>
{{#each post in controller}}
<li>{{post.title}}</li>
<ol>
{{#each comment in post.comments itemController="comment"}}
<li>{{comment.body}}</li>
{{/each}}
</ol>
{{/each}}
</ul>
Properties defined in a App.CommentController are simply not found by the template.
I suspect that Ember.OrderedSet does not implement the itemController param - is there a workaround for this?
You need to use the new expiremental control tag. This will load the view and controller for the specified type:
<ul>
{{#each post in controller}}
<li>{{post.title}}</li>
<ol>
{{#each comment in post.comments}}
{{ control "comment" comment }}
{{/each}}
</ol>
{{/each}}
</ul>
You will need to enable this expiremental feature first. Put this before ember is loaded:
<script type='application/javascript'>
ENV = {
EXPERIMENTAL_CONTROL_HELPER: true
};
</script>
Also, you will need to specify that the controller for comments should not be a singleton, otherwise there will only be one controller instantiated for all comment views:
// this is needed to use control handlebars template properly per
// https://github.com/emberjs/ember.js/issues/1990
App.register('controller:comment', App.CommentController, {singleton: false });