Meteor takes time to know if there's a {{currentUser}} or not - meteor

I've a few code that I want to run only when there's noUser and a few when there's a currentUser.
All these are inside the navigation template. Like so...
{{#if currentUser}}
<li class="nav">Post
</li>
<li class="nav"><a>Ola, {{thisUser}}!</a>
</li>
<li class="nav">Log Out
</li>
{{/if}}
{{#if noUser}}
<li class="nav">Sign Up
</li>
<li class="nav">Login
</li>
{{/if}}
So the problem is that when there's a currentUser(i.e, I'm logged in) and I refresh the page, the code inside the {{#if noUser}} block shows up first then the {{#if currentUser}} block, while the {{#if noUser}} block was only meant to show up when there is no user.
Here's the helper code for the template..
Template.navigation.helpers({
thisUser: function () {
return Meteor.user().username;
},
noUser: function () {
var user = Meteor.user();
if (!user) {
return true;
};
}
});
Don't know what am I doing wrong here. :(
Please help.

You should use if else conditions instead of noUser helper. And to prevent showing "noUser" block while logging in you have to use {{ loggingIn }} helper. Something like this:
{{#if loggingIn}}
<p>Loggin in...</p>
{{else}}
{{#if currentUser}}
<li class="nav">Post
</li>
<li class="nav"><a>Ola, {{thisUser}}!</a>
</li>
<li class="nav">Log Out
</li>
{{else}}
<li class="nav">Sign Up
</li>
<li class="nav">Login
</li>
{{/if}}
{{/if}}
Because Meteor does not know immediately whether user is logged in or not. Therefore you have to use loggingIn helper.

Why don't you refactor your code like this ?
{{#if currentUser}}
<li class="nav">Post
</li>
<li class="nav"><a>Ola, {{thisUser}}!</a>
</li>
<li class="nav">Log Out
</li>
{{else}}
<li class="nav">Sign Up
</li>
<li class="nav">Login
</li>
{{/if}}
You might want to have a look to http://docs.meteor.com/#meteor_loggingin to show a loading indicator if needed.

Related

access parent sub array key handlbars

I have the following array / sub array structure
"filters": {
"types": {
"34": "Ford",
"22": "Jeep",
"18": "Porsche",
},
"locations": [
"Earth",
"Mars",
"Moon",
]
}
and the following handlebars template
{{#if filters}}
{{#each filters}}
<div class="cars">
<ul class="cars__list">
<li class="cars-{{#key}}__title">Filter by {{#key}}:</li>
<li class="cars-{{#key}}__filters">
<ul>
<li class="cars-{{#key}}">View All</li>
{{#each this}}
<li class="cars-{{*want to access filters[key]*}} color={{#key}}">{{this}}</li>
{{/each}}
</li>
</li>
</ul>
</div>
{{/each}}
{{/if}}
I'm having trouble accessing the filters[types] and filters[locations] within the each this loop.
In my CSS I'm using a classes called .cars-type and .cars-location. I want to be able to style each list separately and unfortunately target each li with a class. I want to apply these styles within the each this loop.
I can do it within the filters loop by using {{#key}} but not in the each this loop
I've tried
<li class="cars-{{../filters}}">{{this}}</li>
but this just returns the car type like ford - I want the key ie. '34' in this case
<li class="cars-{{lookup ../filters #index}}">{{this}}</li>
using handlebars helper lookup but again no luck
<li class="cars-{{../this}}">{{this}}</li>
and the above which gives me [object Object]
I've checked out handlebars - is it possible to access parent context in a partial?, handlebars.js: relative paths in partials not working and Lookup helper in handlebars but no luck with any of the solutions
EDIT Here's the HTML output that I want to produce
<div class="cars">
<ul class="cars__list">
<li class="cars-types__title">Filter by types:</li>
<li class="cars-types__filters">
<ul>
<li class="cars-types">View All</li>
<li class="cars-types color-34">Ford</li>
<li class="cars-types color-22">Jeep</li>
<li class="cars-types color-18">Porsche</li>
</ul>
</li>
</ul>
<ul class="cars__list">
<li class="cars-locations__title">Filter by locations:</li>
<li class="cars-locations__filters">
<ul>
<li class="cars-locations">View All</li>
<li class="cars-locations color-0">Earth</li>
<li class="cars-locations color-1">Mars</li>
<li class="cars-locations color-2">Moon</li>
</ul>
</li>
</ul>
</div>
You should reconsider your HTML because a ul cannot be a direct child of another ul. See https://developer.mozilla.org/en/docs/Web/HTML/Element/ul#Usage_context
With that said, we can solve your problem. The Handlebars docs have our answer:
Nested each blocks may access the interation variables via depth based
paths. To access the parent index, for example, {{#../index}} can be
used.
Therefore, your problematic line should look like the following:
<li class="cars-{{#../key}} color-{{#key}}">{{this}}</li>

Passing spacebar data context from parent template to child

I am having a silly trouble with nested templates. I want to create a dropdown menu with 4 main categories and about 2-3 subcategories for each main category.
<template name="Warehouselist">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"> {{warehouse}} <span class="caret"></span></a>
<ul class="dropdown-menu">
{{#each Forms}}
{{>Form}} //Pass {{warehouse}} here
{{/each}}
</ul>
</li>
</template>
<template name="Form">
<li id="EWPacking">{{FormName}}</li>
</template>
The problem is that I don't know how to pass the {{warehouse}} data to the child template's helper in order so I can do something like this.
Template.bonus.helpers({
Userform: function(){
return UserForms.find({});
},
warehouse: function(){
return Warehouse.find({});
},
});
Template.Warehouselist.helpers({
Forms: function(Warehouse){
return Forms.find({Warehousename:Warehouse});
}
});
The point is that the helper of the child template has to return different data, depending on what is the Category of the parent element.
Use parent data context in the child template 'Form':
<template name="Warehouselist">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">{{warehouse}}<span class="caret"></span>
</a>
<ul class="dropdown-menu">
{{#each Forms}}
{{>Form}}
{{/each}}
</ul>
</li>
</template>
<template name="Form">
<li id="EWPacking">
{{FormName}} - {{../warehouse}}</li>
</template>
And change your javascript for the Warehouselist template helper. Get the warehouse from the data context with Template.currentData() and pass it in the Forms.find().
Like this:
Template.Warehouselist.helpers({
Forms: function(){
var warehouse = Template.currentData().warehouse;
console.log('warehouse:', warehouse);
return Forms.find({Warehousename: warehouse});
}
});
If you want to pass warehouse to the child template like you asked use:
(BUT: this is not needed if you follow the solution above!)
{{#each Forms}}
{{>Form warehouse=warehouse}}
{{/each}}

Handlebars - partial template not getting the context

I have pre compiled all my templates into one js file and loaded the js in the page.
I have 3 templates
Template 1 - a.handlebars
<ul>
{{#each this}}
<li class="a">
{{#key}}
{{> b}}
</li>
{{/each}}
</ul>
Template 2 - b.handlebars
<ul>
{{#each this}}
<li class="b">
{{#key}}
{{> c}}
</li>
{{/each}}
</ul>
Template 3 -c.handlebars
<ul>
{{#each this}}
<li class="c">
{{ this }}
</li>
{{/each}}
</ul>
I have the following JS which load data to the template
var menu= {
a1:{
b1:[c1, c2, c3],
b2: [c4, c5, c6]
},
a2:{
b3:[c7, c8],
b4: [c9]
}
};
Handlebars.templates.a(menu);
The first template (a.handlebars) loads a1 and a2. But when the first template loads the partials b.handlebars it fails. I tried to put a log statement to see what is that I am getting for "this". I got 4 spaces and it was of type string.
I do not understand why b.handlebar is getting a string when I thought I will be getting (example for a1)
{
b1:[c1, c2, c3],
b2: [c4, c5, c6]
}
Previously,I did not pre compile the handlebars. I had all the handlebars in my html and compiled it using Handlebars.compile it worked fine. I do not know why the code is failing after per compiling.
Any help is highly appreciated.
I am trying to get his as my final result:
<ul>
<li class="a">a1
<ul>
<li class="b">b1
<ul>
<li class="c">c1</li>
<li class="c">c2</li>
<li class="c">c3</li>
</ul>
</li>
<li class="b">b2
<ul>
<li class="c">c4</li>
<li class="c">c5</li>
<li class="c">c6</li>
</ul>
</li>
<li class="b">b3</li>
</ul>
</li>
<li class="a">a2
<ul>
<li class="b">b3
<ul>
<li class="c">c7</li>
<li class="c">c8</li>
</ul>
</li>
<li class="b">b4
<ul>
<li class="c">c9</li>
</ul>
</li>
</ul>
</li>
</ul>
But I am getting this. Since the b.handlebars is not getting the object data.
<ul>
<li class="a">a1
<ul>
</ul>
</li>
<li class="a">a2
<ul>
</ul>
</li>
</ul>
My apologies for the very lengthy post. I have been trying to find a solution for this for a while now. Again, any help to resolve this issue would be great.
Thanks.
The issue was caused due to compiling the handlebar/template files using grunt.
Command: "grunt handlebars"
Once I compiled the files using handlers itself, the code started working.
Command: handlebars template_files -f output_file
If anyone knows how to make the compiled code work using grunt command I would definitely would like to know. Thanks.

For each loop passvarible to other for each loop meteor

I need to pass the variable to helper function Please help me.
<div class="sidebar">
<ul class="dropdown-menu" style="display: block; position: static;">
{{#each search_family_list}}
<li class="dropdown-submenu active"><img src="" />{{ description }}
<ul class="dropdown-menu">
{{#each material_list}}
<li>atlanta</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
</div>
In the above example i need to pass the family_id to the material_list helper function.
Template.header.helpers({
material_list: function ()
{
return Session.get("search_family_list");
}
});
Please help me.
It is likely you can access family_id as a property of this inside your helper.
Template.header.helpers({
material_list: function () {
var family_id = this.family_id;
return Session.get("search_family_list");
}
});
The function context of a template helper can be used to access the current data context.

Meteor accounts-list

I want to display all registered accounts in my meteor app. I published and subscibed to the Meteor.users collection and build a template to show email-addresses. The problem is I don't understand how I should navigate the data.
<template name="contacts">
<br>
<ul class="list-group">
{{#each users}}
<li class="list-group-item">
<span class="badge">14</span>
{{emails}}
</li>
{{/each}}
</ul>
</template>
{{emails}} is an array with json-objects and I don't know how to handle it to get the "address" field displayed.
This is my JS:
Template.kontakte.users = function (){
return Meteor.users.find();
}
First create a subtemplate, looks better:
<template name="contacts">
<ul class="list-group">
{{#each users}}
{{> user}}
{{/each}}
</ul>
</template>
<template name="user">
<li class="list-group-item">
<span class="badge">14</span>
{{email}}
</li>
</template>
In template user the userObject is available via this pointer. The email can be shown with helper functions.
Template.user.helpers({
email: function() {
return this.emails[0].address;
}
});
Note, this just shows the first email in your array.

Resources