How to handle the array of objects in Ember Js Handlebars - javascript

I'm getting the response from the server like
category:{
listOfCategory: [
"diabetes",
"general"
],
id:1
}
using Ember data findAll method. I'm returning this to my model and I'm trying to display in hbs file using each loop.
js code
model(){
return this.store.findAll('category');
}
hbs code
{{#each model as |category|}}
<h1>{{category.listOfCategory}}</h1>
{{/each}}
Output :
diabetes,general
I want to display as separate category.

Given the data modify your each loop:
{{#each model as |category|}}
{{#each category.listOfCategory as |cat|}}
<h1>{{cat}}</h1>
{{/each}}
{{/each}}
Your loop is calling for the array of categories, instead of looping through the category array elements.

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

Passing template instance data as a keyword argument to a nested template

I have a template, called skillbar, which takes two keyword arguments, title and value.
So, for example, I could type:
{{>skillbar title="strength" value=51}}
To render a skillbar with the label "strength" that has its progress bar filled up 51%.
I have a bunch of these skillbars I would like to create and rather than doing something like:
{{>skillbar title="strength" value=51}}
{{>skillbar title="willpower" value=80}}
{{>skillbar title="imagination" value=30}}
Id rather create a separate template, which I can register a helper on that contains an array of objects that I can use as parameters.
Template.abilities.helpers({
abilities: [
{title: 'strength', value: 51},
{title: 'willpower', value: 80},
{title: 'imagination', value: 30}
]
});
Presumably then, I could {{#each}} over the abilities array in my markup can create the skillbar template instances that way.
This encapsulates the essence of what I want to do, but it throws a syntax error:
<template name="abilities">
{{#each abilities}}
{{>skillbar title={{title}} value={{value}} }}
{{/each}}
</template>
Use this syntax instead :
<template name="abilities">
{{#each abilities}}
{{> skillbar}}
{{/each}}
</template>
When invoking a child template, if you don't pass any argument its current data context will be set to the parent one, which happens to be the currently iterated over ability from the {{#each}} loop.
Alternatively you could use this syntax :
<template name="abilities">
{{#each abilities}}
{{> skillbar title=title value=value}}
{{/each}}
</template>
But in this specific case it would be redundant, but could be useful to rename parameters for whatever reason.

Meteor Display Child Array Elements #each

I'm trying to use Meteor's #each to display a JSON Object from Mongo with children. Say it looks like so:
{
data: {dorem: 'ipsum', dolor:'sit'},
amet: 'abcdefg'
}
Using #each, I currently have something like this
<template name="base">
{{#each stuff}}
{{> info}}
{{/each}}
</template>
The info template looks something like this
<template name="info">
{{data.dorem}}
</template>
The method I'm using to generate stuff is
Template.base.stuff = function () {
return DBThatHasStuffInIt.find({sort:{ _id : -1 }});
};
However, it is not working. Nothing is being displayed. The base template has been added, as well.
Does anybody know what the problem might be?
Your find, requires a selector:
return DBThatHasStuffInIt.find({}, {sort:{ _id : -1 }});

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.

Single Object content with handlebars

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.

Categories

Resources