Single Object content with handlebars - javascript

I have been using ember for a few days now, but i ran to this simple problem:
I made an ajax call and return the results to the model in the route. Basically the call will return a single json object. As i read in the guide, the model will be sent to the 'content' of the controller as below. The problem is how to get the data printed to the template? This is not working:
The Controller:
App.IndexController = Ember.ObjectController.extend({
content: [{name:'smith', age:'20',lastname:'jonnie'}]
});
Handlebars:
<p>{{name}}, {{age}}, {{lastname}}</p>

The content property is an array, so you rather loop over it to get your items out
template
<ul>
{{#each item in controller.content}}
<li>{{item.name}}</li>
{{/each}}
</ul>
or try something like this:
IndexController
App.IndexController = Ember.ObjectController.extend({
content: [{name:'smith', age:'20',lastname:'jonnie'}],
firstObject: Ember.computed.alias('content.firstObject')
});
template
<p>{{firstObject.name}}, {{firstObject.age}}, {{firstObject.lastname}}</p>
Working example.
Hope it helps.

Related

Find all routes defined in Iron Router

Is there a way to add a site map dynamically for all paths which are defined in the Iron Router Router?
I'm thinking of something like this:
<ul>
{{#each paths}}
<li>{{route}}</li>
{{/each}}
</ul>
Also, maybe corresponding sub-paths which will be displayed in a child ul?
Obviously I could also just create the list manually, but for an app with 50+ links this is quite of a work.
Certainly! As Kassym noted, Router.routes contains a list of all the routes. However it contains the router functions, so you'll have to go and grab their names with route.getName(). The default route doesn't have a name, so you'll have to grab the .path() instead.
The whole thing should look like this in your helper:
Template.allRoutes.helpers({
paths: function () {
var allRoutes = _.map(Router.routes, function(route){
var routeName = typeof route.getName() === 'undefined' ?
route.path() :
route.getName();
return {route: routeName}
});
return allRoutes
}
});
And this in your template:
<template name="allRoutes">
{{#each paths}}
<li>{{route}}</li>
{{/each}}
</template>
Working Demo in MeteorPad
Note: Remember to enclose pathFor in curly brackets because it is a helper method. It will execute javascript and inherit the current datacontext, so you can pass it any property from the current context.
In order to display an sub paths of n depth, you can recursively call your template like this:
<template name="subpaths">
<ul>
{{#each subpaths}}
<li>
{{path}}
{{#if subpaths}} {{>subpaths}} {{/if}}
</li>
{{/each}}
</ul>
</template>
Demo in meteor pad
For more info, see getting the names of all routes for the accounts-entry package

Return object as ember-model with matching key in array of JSON objects

What I'm trying to accomplish is to return only one object to the model and loop through it's properties in a handlebars template. Thanx-a-Lot for any help!
My response looks like this:
{"U+554A":{
"id":1,
"unihex":"U+554A",
"num_reference":"呵",
"totalStrokes":10,
"kMandarin":"a\n",
"kDefinition":"exclamatory particle\n"},
"U+611B":{
"id":2,
"unihex":"U+611B",
"num_reference":"愛",
"totalStrokes":13,
"kMandarin":"\u00c3\u00a0i\n",
"kDefinition":"love, be fond of, like\n"}
}
I tried everything. The most obvious being these two, just as a tryout, but the ember inspector shows no model is set:
var sinograms = Ember.$.getJSON(apiurl);
return sinograms['U+554A'];
I also tried:
var sinograms = Ember.$.getJSON(apiurl);
return sinograms[0];
NB:
I can change the response format if necessary.
I know it works when I loose the object-keys (without "U+554A"), but then how do I select the matching character.
#abuani: Upon your request. Thanx btw.
//app.js
App = Ember.Application.create();
App.Router.map(function() {
this.resource('signup');
this.resource('login');
this.resource('profile');
this.resource('overview');
this.resource('practice');
});
App.OverviewRoute = Ember.Route.extend({
model: function() {
var url = 'http://localhost/~hiufung/RoadToChinese/index.php/api/sinograms/random?limit=2';
var sinograms = Ember.$.getJSON(url);
return sinograms;
}
});
//index.html (inline template)
<script type="text/x-handlebars" id="overview">
<header class="bar bar-nav">
<a class="icon icon-left pull-left" href="back"></a>
<h1 class="title">RoadToChinese</h1>
<a id="showRightPush" class="icon icon-gear pull-right" href="overview-settings"></a>
</header>
<div class="content">
<div class="content-padded">
{{#each object in model}}
<p>{{object.num_reference}}<p>
{{/each}}
</div>
</div>
</script>
I can't add a comment to your initial question, but can you please post a few other pieces of code:
The router that's loading this(I imagine this is being done in your model function), the setupController if you have one, and the template that's trying to render the object. Without this information, there's little I can do to help.
EDIT Since there's code:
I should have noticed, your model is return an objects when Ember expects the model to be an array of objects. The first thing you should do is make the return from the server an Array. If you don't have control over this, then you can change your model to return
return Ember.A([sinograms]);
And that should work.
After that though, you can remove the nested object within each object. If you don't remove that, then you also need to make the inner objects an Array so you can iterate over it.
Let me know how this goes.
Here's the JSBIN

EmberJS: Defining Controller Breaks Route Modal

I'm fairly new to Ember and I'm starting to write more complex apps. I've been pulling hair trying to figure out why defining a controller for the index breaks the index route's model population.
I've tried the "setupcontroller" function, but still no luck.
Here's the route code:
App.IndexRoute = Ember.Route.extend({
model: function () {
return Ember.RSVP.hash({ //return promises for both models here
featuredJobs: $.getJSON('http://api.*********/featured/jobs', {'token': guestToken}),
featuredEmployers: $.getJSON('http://api.********/featured/employers', {'token': guestToken})
})
}
});
When I add App.IndexController = Ember.Controller.extend({... it breaks the model's {{#each}} helper. (not the app). I can see the model assigned to the route in the Ember inspector. Here's the template:
<div class="panel-body">
<div class="list-group ft-jobs">
{{#each featuredJobs}}
{{#linkTo 'job' _id class="list-group-item"}}
<h4 class="list-group-item-heading">{{title}}</h4>
<p class="list-group-item-text">{{description}}</p>
{{/linkTo}}
{{else}}
<p class="text-center">Sorry, no featured jobs are available.</p>
{{/each}} //END OF SNIPPET
Your controller needs to extend ObjectController since it's being backed by an object.
http://emberjs.jsbin.com/OxIDiVU/134/edit

Ember.js generate html from json with iteration

I'm supposed to use ember.js for a project. I'm converting a json into a HTML view. The json looks something like this:
{
"title": "Some H1 title",
"children": [
{"title": "Some H2 title",
"children": .....
}
]
}
So the result should look like
Some H1 Title
Some H2 Title
Doesn't really matter if it's dynamic with handlebars or static.
What is the recommended emberjs way of doing this? Load the whole json into a data model and go from there? Or just give the object to handlebars? (there is the need for some basic if else logic by the way so the last option might not be the best (e.g. needs more code)).
If the data in json has some meaning in the data model of your application, then you should place it in a structure of ember objects and assign them to properties of the controller. If you only need the json data to be displayed and has no meaning in your application's data model, then you can simply assign it directly as a property to the view or controller.
In all cases you will need a handlebars template that will display the data stored in those properties.
For example if you have json data that is composed of objects with a string as title and array of the same objects as children and you want to display all titles of all children regardless of depth you could do something like,
http://emberjs.jsbin.com/UgaVAvIZ/1/edit
hbs
<script type="text/x-handlebars">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
<h1>{{title}}</h1>
{{partial "childrenPartial"}}
</script>
<script type="text/x-handlebars" data-template-name="_childrenPartial">
{{#each child in children}}
<h2>{{child.title}}</h2>
{{#with child.children}}
{{partial "childrenPartial"}}
{{/with}}
{{/each}}
</script>
js
App = Ember.Application.create();
App.Router.map(function() {
// put your routes here
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return {"title": "Some H1 title","children": [{"title": "Some H2 title","children": []}]};
}
});
Please note that using a partial as shown is only one of many other approaches. In this approach the json data has been assigned as model to the specific route and the corresponding view with the help of a partial display the required data.

How do I load a model from ember-data into a handlebars.js template?

I have an Ember.js app that gets its data from a JSON resource, and puts it into an ember-data model (Not sure about the terminology) for use in a Handlebars.js view. When I try to put the data into the template context, I get this error:
TypeError: arrangedContent.addArrayObserver is not a function
I've made a Fiddle to demonstrate it. Use the actual Fiddle to view the code, use the following link to see the error (which makes it try to put data into the template/view):
http://fiddle.jshell.net/WZ4vt/show/#/item/1
s = App.store.find(App.Item, 1);
s.get('value1');
The above works fine, and returns "test".
I updated the fiddle: http://jsfiddle.net/WZ4vt/3/
Your mistake was to declare your ItemController as ArrayController, but your Data Store just returned a single entity. I fixed that and additionally your Handlebars Template, as this was not working either.
So this is the new controller declaration:
ItemController: Em.Controller.extend(),
And the updated Template:
<script type="text/x-handlebars" data-template-name="item">
{{content.value1}}
{{content.value2}}
</script>​
Here the working link: http://fiddle.jshell.net/WZ4vt/3/show/#/item/1

Categories

Resources