Consider Below Code.
{{#each assignments}}
{{#with eachClientDetails}}
{{#quickRemoveButton collection=assignment _id=this._id }}
Delete
{{/quickRemoveButton}}
{{/with}}
{{/each}}
In above code, I am iterating each assignment and each assignment has single Client Detail. With each Client Detail I am adding Delete button.
Helper:
eachClientDetails(){
var client = Clients.find({_id: this.clientId}).fetch()[0];
console.log(client);
return client;
}
But the problem is, while assigning attributes to _id of quickForm, I can only assign data from current context(i.e. this._id). All I need is to access context of assignment (desired like _id=../_id). But I get below error,
Can only use `this` at the beginning of a path.
Instead of `foo.this` or `../this`, just write `foo` or `..`.
Is it possible using any helper and stuff to get the parent templates _id
Your issue with overwriting contexts could be solved by using #each in and #let instead of #each and #with:
{{#each assignment in assignments}}
{{#let client=(eachClientDetails assignment)}}
{{#quickRemoveButton collection=assignment _id=assignment._id }}
Delete {{client.name}}
{{/quickRemoveButton}}
{{/let}}
{{/each}}
Here, {{client.name}} has been added just to show how to access client's fields.
And helper's code:
eachClientDetails(assignment){
var client = Clients.findOne({_id: assignment.clientId});
console.log(client);
return client;
}
Related
If my parent context has access to a property (index), can I pass it into a subexpression? I can't seem to get it to work. I've confirmed that that with block works with a static value passed to it (1)
// Parent template
-----------------------------------------------------------------------------
{#child {{../report.ResourceName}}--{{Name}} #data.parentIndex={{#index}} }
// Child template
-----------------------------------------------------------------------------
{{parentIndex}} // displays correctly as 2
// does not render
{{#with (lookup report.sections parentIndex)}}
Rendered: {{name}}
{{/with}}
// renders correctly
{{#with (lookup report.sections 2)}}
Rendered: {{name}}
{{/with}}
when you use dynamic data in a child template call (like an index in a each iteration) you have to be careful because things may not work as your expect.
for example when using something like this
{{#each report.sections}}
{#child child #data.parentIndex={{#index}} }
<br />
{{/each}}
what is passed to the actually child template is "parentIndex": "0 ", it may not be obvious but when you pass data using #data.parentIndex syntax any space matters and since you are using {#child child #data.parentIndex={{#index}} } that contains a space (}) in the end, then the final value contains that space.
the correct way to pass this should be {#child child #data.parentIndex={{#index}}} but this throws a handlebars error because it gets confused by the brackets of the child call syntax.
the way that works is like this:
parent template:
{{#each report.sections}}
{{{callChild #index}}}
<br />
{{/each}}
helpers of parent template:
function callChild(parentIndex) {
return '{#child child #data.parentIndex=' + parentIndex + '}'
}
child template:
{{parentIndex}}
{{#with (lookup report.sections parentIndex)}}
Rendered: {{name}}
{{/with}}
the reason this works is because we are avoiding handlebars getting confused by the brackets syntax, we do that by constructing the child call dynamically with a helper which in the end gets resolved after handlebars have processed the template.
finally here is a live example of this case
hope it helps you.
I am using Meteor and tried to use #each, but I have a problem with it. I have some values stored in a var like:
var a = [465,77987,2132,2];
I wanted to render each value of a on HTML. I thought #each would be the right way to do it? Actually I don´t know how to use #each and the docs I found don´t really help me. I have written the following code:
JS:
Template.page.helpers({
values: function() {
return a;
}
});
HTML:
{{#each values}}
{{> page}}
{{/each}}
But this is obviously wrong, because I get the this Error in the client console:
Error: {{#each}} currently only accepts arrays, cursors or falsey values.
I thought it is an array or not?
Update
So now I have used the #each in approach, however I still get the same error-message:
Error: {{#each}} currently only accepts arrays, cursors or falsey
values. at badSequenceError (observe-sequence.js:183) at
observe-sequence.js:148 at Object.Tracker.nonreactive (tracker.js:631)
at observe-sequence.js:125 at Tracker.Computation._compute
(tracker.js:339) at Tracker.Computation._recompute (tracker.js:358) at
Object.Tracker._runFlush (tracker.js:523) at onGlobalMessage
(meteor.js:401)
JS:
Template.page.helpers({
values: function() {
var a = [465,77987,2132,2]
return a;
}
});
HTML:
{{#each a in values }}
{{> a}}
{{/each}}
Update 2
I know now where this error comes from. I'm sorry, actually my first post was not correct. I forgot, that these values [465,77987,2132,2] are not directly stored in var a.
They are stored in a Session-Variable and var a = Session.get('values') and I think that´s the point why I get this error...So, I don´t think that this can work with #each ? Maybe I have to save it to my MongoDB first and than render it on the HTML or something like that.
try the each/in construct:
{{#each value in values}}
{{value}}
{{/each}}
c.f. http://blazejs.org/guide/spacebars.html#Each-in
you specified the entire template inside the each, which is what it was complaining about.
I'll put all the code in an example. Consider the 'import' only if you are using the recommended application structure. The files must be in the same directory. First in page.js:
import './page.html';
Template.page.helpers({
values: function() {
var a = [465,77987,2132,2];
return a;
}
});
Second in page.html:
<template name="page">
{{#each a in values}}
{{a}}
{{/each}}
</template>
I use very often in my code (and I don't know if I'm right to use it):
{{#each model.posts as |post|}}
<div>post.title</div>
{{else}}
<div>I'm loading the posts...</div>
{{/each}}
and until today everything OK.
But now I don't know if the model.posts is empty or not.
How to show an error instead of loading forever an empty array?
A relationship on a model returns a PromiseArray which resolves to a RecordArray. On the RecordArray you can check isLoaded. However you can't access this property, because the PromiseArray does not proxy this to the underlaying RecordArray. However the PromiseArray implements the PromiseProxyMixin, which has isPending and isSettled available.
Checkout this twiddle for a working solution.
Basically this is the working code:
{{#each model.posts}}
{{else}}
{{#if model.posts.isPending}}
<div>lade...</div>
{{else}}
<div>nix da :(</div>
{{/if}}
{{/each}}
These two options come to my mind:
Use ember-promise-helpers, very easy to use directly in your template: https://github.com/fivetanley/ember-promise-helpers
As already stated, if you are working RecordArray check the isLoaded property.
Meteor Newbie here!
I have a page where all the open orders are displayed. The order details are stored in a collection. A Template helper will return the order details.
Template.delivery.helpers({
openOrders: function(){
return Orders.find({status: "open"});
}
});
The template look some what like this.
{{#if openOrders}}
{{#each openOrders}}
Date: {{createdAt}}
Total items: {{items.length}}
Location: {{location}} //It prints the location _id
{{/each}}
{{/if}}
The Order Collection only have the _id of the location. The Location details are stored in a Collection named Locations.
I want to display the location name (which is stored in the Location collection) instead of the _id.
I created a Template helper which returns the Location details, but how can I link these to helpers so that the Location name is displayed instead of Location _id?
As you're using mongodb in a relational database fashion, you need to install publish-composite package to make sure all the necessary data are subscribed.
When you use each, it will set the this to the current thing that is being iterated over. This will allow you to use this in your helper to perform lookups. So in this case, if you're using a helper to get the orders:
orders: function () {
return Orders.find({ status: "orders" });
}
Then when you iterate over it with {{#each}}, this is set to the current order, meaning your location helper with look like this:
location: function () {
return Locations.findOne(this.locationId);
}
Putting it all together in the template it would be like:
{{#if Template.subscriptionsReady}}
{{#each orders}}
<h1 class="title">Order #{{_id}}</h1>
{{#with location}}
<div class="location">
<span>Latitude: {{ latitude }}</span>
</div>
{{/with}}
{{/each}}
{{/if}}
Keep in mind: this will only work if you also publish your locations.
I have a template.
{{#each dbModel in model}}
<h2>Database Name : {{dbModel.databaseName}}</h2>
<h3>Select Table:
{{view Ember.Select
content=dbModel.tables
optionValuePath="content.tableName"
optionLabelPath="content.tableName"
valueBinding = "dbModel.selectedTable"
selectBinding = "dbModel.selectedTable"
}}
</h3>
<h2>Selected Table is : {{dbModel.selectedTable}}</h2>
{{#each table in dbModel.tables}}
{{dbModel.selectedTable}}
{{#matchTable table.tableName dbModel.selectedTable}}
//Get fields is selected table match with table name
{{/matchTable}}
{{/each}}
Now In the matchTable helper I am getting value of table.tableName but for dbModel.selectedTable is undefined.
dbModel.selectedTable is not part of actual model, I have added this to controller as follows.
App.DatabaseController = Ember.ArrayController.extend({
selectedTable:[],
actions: {
cancel: function () {
// something
}
}
});
When I change the value of select it automatically updates the information in <h2> tag. So it means that the value is setting and got bind properly. But for helper when I try to pass it it simply shows undefined. I searched and found that can use ../dbModel.selectedTable. Still it is undefined. Anyone please guide.
What is the way to pass the parent to the helper in each loop?
Your #each loop drops you into the scope of the tables array. ../ places you in the scope of the dbModel object. To access selectedTable within the loop, use ../selectedTable