User undefined momentarily in Meteor - meteor

I set up a template with materialize tabs in meteor with conditional formatting if a user is an admin. Unfortunately, this only works intermittently. Does anyone understand why?
The template:
<template name="tabs">
<div class="row">
<div class="col s12">
<ul id="nav-mobile" class="tabs right darkgrey">
{{#if currentUser}}
<li class="tab col s4">Forms</li>
<li class="tab col s4">Report</li>
{{/if}}
{{#if isAdmin}}
<li class="tab col s4">Edit</li>
{{/if}}
</ul>
</div>
</div>
<div class="black-text" id="edit">edit</div>
<div class="black-text" id="forms">forms</div>
<div class="black-text" id="report">report</div>
</template>
The js (admin user is logged in):
Template.tabs.helpers({
isAdmin: function() {
var u = Meteor.user();
try {
if (u == undefined) {
console.log("user was undefined momentarily?");
console.log(u);
console.log(u.username);
}
} catch (err) {
console.log(err);
}
return u.username == "admin";
//return true;
}
});
I then get some strange output (browser console) + stacktrace:
user was undefined momentarily? forms.js:29:11
undefined forms.js:30:11
TypeError: u is undefined
Stack trace:
.isAdmin#http://localhost:3000/forms.js?bb20f376b815e838347b13b36da9b44e65fad3d9:31:11
bindDataContext/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2880:14
Blaze._wrapCatchingExceptions/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1651:14
wrapHelper/</<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2928:14
Template._withTemplateInstanceFunc#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3476:12
wrapHelper/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2927:1
Spacebars.call#http://localhost:3000/packages/spacebars.js?7bafbe05ec09b6bbb6a3b276537e4995ab298a2f:172:12
#http://localhost:3000/template.forms.js?70bd177091ff1ea210ad3e4ae259b54f523adf01:42:12
Blaze.If/</<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2626:44
viewAutorun/</<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1865:16
Template._withTemplateInstanceFunc#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3476:12
viewAutorun/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1864:1
Blaze._withCurrentView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2197:12
viewAutorun#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1863:1
Tracker.Computation.prototype._compute#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:327:5
Tracker.Computation#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:243:5
Tracker.autorun#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:566:11
Blaze.View.prototype.autorun#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1875:14
Blaze.If/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2625:1
fireCallbacks#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1941:9
Tracker.nonreactive#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:593:12
Blaze._fireCallbacks/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1938:5
Blaze._withCurrentView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2197:12
Blaze._fireCallbacks#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1937:3
Blaze._createView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1955:3
Blaze._materializeView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1998:3
materializeDOMInner#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1476:9
Blaze._materializeDOM#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1428:7
Blaze._materializeView/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2040:25
Tracker.nonreactive#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:593:12
Blaze._materializeView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2004:3
Blaze.render#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2296:3
Template.body.renderToDocument#http://localhost:3000/packages/templating.js?376767bb0d2463b3b2615a1b90e77f6b22d39d7b:105:14
ready/runStartupCallbacks#http://localhost:3000/packages/meteor.js?43b7958c1598803e94014f27f5f622b0bddc0aaf:785:8
ready#http://localhost:3000/packages/meteor.js?43b7958c1598803e94014f27f5f622b0bddc0aaf:787:3
forms.js:34:9
Exception in template helper: .isAdmin#http://localhost:3000/forms.js?bb20f376b815e838347b13b36da9b44e65fad3d9:36:7
bindDataContext/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2880:14
Blaze._wrapCatchingExceptions/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1651:14
wrapHelper/</<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2928:14
Template._withTemplateInstanceFunc#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3476:12
wrapHelper/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2927:1
Spacebars.call#http://localhost:3000/packages/spacebars.js?7bafbe05ec09b6bbb6a3b276537e4995ab298a2f:172:12
#http://localhost:3000/template.forms.js?70bd177091ff1ea210ad3e4ae259b54f523adf01:42:12
Blaze.If/</<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2626:44
viewAutorun/</<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1865:16
Template._withTemplateInstanceFunc#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3476:12
viewAutorun/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1864:1
Blaze._withCurrentView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2197:12
viewAutorun#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1863:1
Tracker.Computation.prototype._compute#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:327:5
Tracker.Computation#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:243:5
Tracker.autorun#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:566:11
Blaze.View.prototype.autorun#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1875:14
Blaze.If/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2625:1
fireCallbacks#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1941:9
Tracker.nonreactive#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:593:12
Blaze._fireCallbacks/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1938:5
Blaze._withCurrentView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2197:12
Blaze._fireCallbacks#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1937:3
Blaze._createView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1955:3
Blaze._materializeView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1998:3
materializeDOMInner#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1476:9
Blaze._materializeDOM#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1428:7
Blaze._materializeView/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2040:25
Tracker.nonreactive#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:593:12
Blaze._materializeView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2004:3
Blaze.render#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2296:3
Template.body.renderToDocument#http://localhost:3000/packages/templating.js?376767bb0d2463b3b2615a1b90e77f6b22d39d7b:105:14
ready/runStartupCallbacks#http://localhost:3000/packages/meteor.js?43b7958c1598803e94014f27f5f622b0bddc0aaf:785:8
ready#http://localhost:3000/packages/meteor.js?43b7958c1598803e94014f27f5f622b0bddc0aaf:787:3
meteor.js:888:11
Exception from Tracker afterFlush function: meteor.js:888:11
TypeError: d[0] is undefined meteor.js:888:11
b.init/<#http://localhost:3000/packages/materialize_materialize.js?76da33aa1a8c219b9d3d6cde626664cb18f469c0:38:3543
.each#http://localhost:3000/packages/jquery.js?dd8bac56f8fd3666d433d2285ae01e52597cc51a:417:14
jQuery.prototype.each#http://localhost:3000/packages/jquery.js?dd8bac56f8fd3666d433d2285ae01e52597cc51a:169:10
b.init#http://localhost:3000/packages/materialize_materialize.js?76da33aa1a8c219b9d3d6cde626664cb18f469c0:38:3098
a.fn.tabs#http://localhost:3000/packages/materialize_materialize.js?76da33aa1a8c219b9d3d6cde626664cb18f469c0:38:4767
#http://localhost:3000/forms.js?bb20f376b815e838347b13b36da9b44e65fad3d9:21:5
fireCallbacks/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3155:9
Template._withTemplateInstanceFunc#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3476:12
fireCallbacks#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3151:1
Template.prototype.constructView/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:3244:5
Blaze.View.prototype.onViewReady/fire/</<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1778:11
Blaze._withCurrentView#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:2197:12
Blaze.View.prototype.onViewReady/fire/<#http://localhost:3000/packages/blaze.js?a5c324925e5f6e800a4c618d71caf2848b53bf51:1777:9
Tracker._runFlush#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:501:11
onGlobalMessage#http://localhost:3000/packages/meteor.js?43b7958c1598803e94014f27f5f622b0bddc0aaf:372:11
meteor.js:888:11
TypeError: d[0] is undefined

While you can rely on Meteor.userId() to check if a user is logged in or not as it is always available, Meteor.user() is actually a mongo collection like any other. Thus, it may take some time for this collection to be ready and data to be retrieved from the server.
To solve this helpers are rerun reactively as soon as the reactive data used inside change. So I would get rid of the try/catch part and just return u.username == "admin" with a "guard" so it checks the username only when the data is available (i.e. u !== null), like this:
Template.tabs.helpers({
isAdmin: function() {
var u = Meteor.user();
return u && u.username == "admin";
}
});

Related

html element innerHtml change with session and server code

This webApp has a header which displays a short message based on user interaction by using session in order to make it reactive. I would like to give the server the priority to display its own message it it has one.
Like if server.message is "" then use client session else use server message.
Should I use global helper? or How can go about it? Thanks.
Template.header.helpers({
headerLabel: function(){
return Session.get('taskSelected');
}
});
<template name="header">
<h1>
<button class="col-xs-2 mainMenu" type="button">☰</button>
</h1>
<h3>
<label class="col-xs-8 text-center">
{{#if headerLabel}}
{{headerLabel}}
{{else}}
Select an item
{{/if}}
</label>
</h3>
<h1>
<button class="col-xs-2" type="button">⋮</button>
</h1>
</template>
Template.mainMenu.events({
'click .menuItem': function (event) {
Session.set('taskSelected', this.menuItem);
});
I think you could do this with reactive variables:
Template.header.onCreated( function() {
this.message = new ReactiveVar( "" );
Meteor.call('serverMessageMethod', function(error, results) {
if( error || !results ) {
Template.instance().message.set(Session.get("yourVariable");
} else {
Template.instance().message.set(results);
}
});
});
Template.header.helpers({
message() {
return Template.instance().message.get();
}
});
You'll have to create the server method to see if there's a message, but other than that this should work.

Meteor RangeError: Maximum call stack size exceeded. on keypress event

Im trying to make a search box to filter down results of my returned collection in the client.
however when i actually try searching I'm getting the above error in the console.
RangeError: Maximum call stack size exceeded.
here is a look at my code.
<body>
{{#isolate}}
<header class="row-fluid">
{{> modules}}
</header>
{{/isolate}}
<div id="main" class="span11">
{{#if currentUser}}
{{#isolate}}
{{> customers_list}}
{{/isolate}}
{{#isolate}}
{{> contacts_list}}
{{/isolate}}
{{/if}}
</div>
</body>
my search form in inside the modules template
<template name="modules">
{{templateLogger "modules"}}
<ul id="module_list" class="nav">
{{#each list}}
<li>
{{name}}
</li>
{{/each}}
<form><input type="text" id="search"></form>
</ul>
and my customers_list template that I'm trying to filter the results
<template name="customers_list">
<table class="table">
<tr>
<th>Name</th>
<th>Address</th>
<th>City</th>
<th>State</th>
<th>Zip</th>
<th>Phone</th>
</tr>
{{#each record}}
<tr>
<td>{{name}}</td>
<td>{{address}}</td>
<td>{{city}}</td>
<td>{{state}}</td>
<td>{{zip}}</td>
<td>{{phone}}</td>
</tr>
{{/each}}
</table>
</template>
and here is the event handler for the search form
Template.modules.events({
'keypress input#search': function (event) {
Session.set("currentFilter", $('input#search'));
}
});
and the form helper do display the results
Template.customers_list.record = function() {
qry = Session.get("currentFilter") || "";
if (qry != "") {
return Customers.find({$or: [ {'name': qry}, {'address': qry}, {'city': qry}, {'state': qry} ] });
} else {
return Customers.find({competitor: null}, {sort: {name: 1}});
};
}
I have no clue what the is causing this error from what i was able to read on other SO posts about the error it seems like its a infinite loop however those were not meteor specific questions and i don't know if that would make a difference? also if there is an infinite loop i cant find it.
any help would be grateful.
This error occurs when you pass large object as an argument to your method. For me for example the first Time I encountered this error, was when I passed a Meteor.Collection as an argument :s . I worked around that by passing the collection name as a String and then using eval() in the Methods to get the Collection on which proceed.
Conclusion: Always use strings, integers, small arrays or really small objects as arguments for methods called from your event handlers.
Changing this:
Template.modules.events({
'keypress input#search': function (event) {
Session.set("currentFilter", $('input#search'));
}
});
To This:
Template.modules.events({
'keyup input#search': function (event) {
Session.set("currentFilter", $('input#search').val());
}
});
I believe you just need the .val() on the jquery dom reference of the input field. Additionally I would recommend using keyup for the event for something like this.
For getting the results out like you want you likely want to use a regular expression. Here's what I'm using in my app.
Template.hudlies.found = function() {
var searchVal = Session.get("searchFilter");
if (searchVal != "") {
var searchResults = Hudlies.find({ name: { $regex: '^.*' + searchVal + '.*', $options: 'i' } });
};
return searchResults;
};

How to make a session variable reactive?

I'm running Meteor 0.5.7, and trying to display a bootstrap alert message when user clicks submit.
client.js
Handlebars.registerHelper('isSuccessful',function(input){
return Session.get("success");
});
Template.form.events({
'click .submit' : function (event, template) {
if (condition) {
Session.set("success", true);
// hide warning, show success
$('#valid_form').show();
$('#invalid_form').hide();
} else {
Session.set("success", false);
// hide success, show warning
$('#valid_form').hide();
$('#invalid_form').show();
}
}
});
Template.form.rendered = function () { $('.alert').hide();};
page.html
<body>
{{> page}}
</body>
<template name='page'>
{{> form}}
</template>
<template name='form'>
<!-- Show Alerts Above Form -->
<div class="alert alert-success" id="valid_form">..</div>
<div class="alert" id="invalid_form">..</div>
{{#if isSuccessful}}
<div>SHOW CONFIRMATION PAGE</div>
{{else}}
<div>SHOW INPUT FIELDS</div>
{{/if}}
<div>
</template>
When the user INITIALLY clicks submit and the condition is not met, they have to click submit again in order to get the warning message. All other times the logic works.
I've looked at this - How does Meteor's reactivity work behind the scenes?, and re-read the Meteor docs on reactive programming parts, but something is still amiss.
Shouldn't the else statement in the client default to a session variable of success == false, and the handlebar template pick it up immediately in the {{else}} block? SLightly confused. Thanks,
The answer to my question appears to be that changing return Session.get("success") to return Session.equals("success",true) in the handlebar registered helper did the trick. From what I'm reading, it has less "invalidations"? - not sure what that's suppose to mean atm, but it's a start!
If your purpose is to hide/show the relevant alerts on a condition, you can just do this instead:
client.js
Template.form.rendered = function() {
// hide all alerts when elements are rendered
$('.alert').alert('hide');
}
Template.form.events({
'click .submit' : function (event, template) {
if (condition) {
// hide warning, show success
$('#valid_form').alert();
$('#invalid_form').alert('hide');
} else {
// hide success, show warning
$('#valid_form').alert('hide');
$('#invalid_form').alert();
}
}
});
page.html:
<body>
{{> page}}
</body>
<template name='page'>
{{> form}}
</template>
<template name='form'>
<div class="alert alert-success" id="valid_form">..</div>
<div class="alert" id="invalid_form">..</div>
</template>

Content wrapped in currentUser re-rendering when user updated

I'm using Meteor and having an issue where my content is being re-rendered when I don't want it to.
I have my main content wrapped in a currentUser if statement which I feel is fairly standard.
{{#if currentUser}}
{{> content}}
{{/if}}
The problem with this is my content template is being re-rendered when I update my user object. Is there any way around this? I don't reference users anywhere inside the content template.
Thank you!
Here's a sample app to replicate my problem:
HTML
<head>
<title>Render Test</title>
</head>
<body>
{{loginButtons}}
{{> userUpdate}}
{{#if currentUser}}
{{> content}}
{{/if}}
</body>
<template name="userUpdate">
<p>
<input id="updateUser" type="button" value="Update User Value" />
User last update: <span id="lastUpdated">{{lastUpdated}}</span>
</p>
</template>
<template name="content">
<p>Render count: <span id="renderCount"></span></p>
</template>
JavaScript
if (Meteor.isClient) {
Meteor.startup(function() {
Session.set("contentRenderedCount", 0);
});
Template.content.rendered = function() {
var renderCount = Session.get("contentRenderedCount") + 1;
Session.set("contentRenderedCount", renderCount);
document.getElementById("renderCount").innerText = renderCount;
};
Template.userUpdate.events = {
"click #updateUser": function() {
Meteor.users.update({_id: Meteor.userId()}, {$set: {lastActive: new Date()}});
}
};
Template.userUpdate.lastUpdated = function() {
return Meteor.user().lastActive;
};
}
if (Meteor.isServer) {
Meteor.users.allow({
'update': function () {
return true;
}
});
}
Update:
I should've explained this example a little. After creating a user, clicking the Update User Value button, causes the render count to increment. This is because it's wrapped in a {{#if currentUser}}. If this is if is removed, you'll notice the render count remains at 1.
Also, you'll need to add the accounts-ui and accounts-password packages to your project.
Meteor will re-render any template containing reactive variables that are altered. In your case the {{currentUser}} is Meteor.user() which is an object containing the user's data. When you update the users profile, the object changes and it tells meteor to re-calculate everything reactive involving the object.
We could alter the reactivity a bit so it only reacts to changes in whether the user logs in/out and not anything within the object itself:
Meteor.autorun(function() {
Session.set("meteor_loggedin",!!Meteor.user());
});
Handlebars.registerHelper('session',function(input){
return Session.get(input);
});
Your html
{{#if session "meteor_loggedin"}}
{{> content}}
{{/if}}

How to create users client side?

I'm working on a intern document-sharing project for a small company. I want to do this with meteor. I'm very common with html/javascript but not with databases.
My problem is to handle the users. Because of my researches here I'm not sure if it's already possible to create users on client side. The official documentation shows some methodes how to deal with users but no examples.
I tried to create a list on server side like this:
Users = new Meteor.Collection("users");
Then I want to insert a user on startup like this:
//on Client side
if (Meteor.isClient) {
var username = "My Name";
Meteor.call("create_user", username, function(error, user_id) {
Session.set("user_id", user_id);
});
}
//on Server side
if(Meteor.is_server) {
Meteor.methods({
create_user: function(username) {
console.log("CREATING USER");
var USER_id = Users.insert({name: username});
return user_id;
},
});
}
But reading the username in the html template doesn't work...
Are there any good examples with a register and login?
Cheers
Adding the accounts functionality is very easy in Meteor.. may it be simple email, password, or by using facebook connect/twitter etc..
do the following to get a simple meteor app with user accounts set up..
meteor create simpleapp
cd simpleapp
add the accounts-ui and accounts-password packages
meteor add accounts-ui
meteor add accounts-password
you simply add other accounts related packages for implementing facebook/twitter/github/google login etc
to list other available meteor packages use this command
meteor list
now edit your simpleapp.html file to this to add login buttons etc..
<head>
<title>simpleapp</title>
</head>
<body>
{{> hello}}
</body>
<template name="hello">
<h1>Hello World!</h1>
{{greeting}}
<input type="button" value="Click" />
{{loginButtons}}
</template>
I simply added {{loginButtons}} to the default html file to add the default login buttons..
now run the meteor app and go to localhost:3000
meteor
you implemented the login functionality without doing much work. 4-5 lines of code, it even takes care of things like forgot password, registering new user etc
next thing is you need to display a particular html when the user is signed in.
you do this using the {{currentUser}} global
you implement it accordingly
<template name="hello">
<h1>Hello World!</h1>
{{greeting}}
<input type="button" value="Click" />
{{loginButtons}}
{{#if currentUser}}
{{> loggedInTemplate}}
{{else}}
{{> loggedOutTemplate}}
{{/if}}
</template>
<template name="loggedInTemplate">
<!-- user is logged in -->
</template>
<template name="loggedOutTemplate">
<!-- user is logged out -->
</template>
You don't need to create a user system manually. Just use the accounts package:
The Meteor Accounts system builds on top of the userId support in publish and methods. The core packages add the concept of user documents stored in the database, and additional packages add secure password authentication, integration with third party login services, and a pre-built user interface.
Your code should work, though. But you're not exposing the username property to the client, so maybe that's why you can't see it in your template.
Ok thank you, that's easy. But so I can not modify the loggedInTemplate or the loggedOutTemplate.
I show you what I've got:
//the html
<head>
<title>myApp | documents</title>
</head>
<body>
<div id="headerBox">
{{> header}}
</div>
<div id="sideBox">
{{> side}}
</div>
<div id="contentsBox">
{{> contents}}
</div>
</body>
<template name="header">
<h1>Company name</h1>
</template>
<template name="contents">
{{#if currentUser}}
<p>Welcome to documents</p>
{{else}}
<h3>Hello! Please log in!</h3>
<p><input type="text" id="username" placeholder="Username"><input type="text" id="password" placeholder="Password"><input type="button" value="log me in!"></p>
{{/if}}
</template>
<template name="side">
<p>Hello {{ activeUser }}</p>
<p><input type="button" value="Create New Document" onclick="createPage()"></p>
<h3>Documents:</h3>
</template>
and
//client.js
Pages = new Meteor.Collection("pages");
Meteor.startup(function() {
Session.set("activeUser", "please log in!");
});
Template.side.activeUser = function() {
return Session.get("activeUser");
};
and
//server.js
Meteor.startup(function() {
Accounts.createUser({username: "MyName", email: "me#example.com", password: "123456"});
});
and I'm searching for a manual way to log this user created on startup in. And of course later to allow this user to create new users...
The problem is adding
// Returns an event_map key for attaching "ok/cancel" events to
// a text input (given by selector)
var okcancel_events = function (selector) {
return 'keyup '+selector+', keydown '+selector+', focusout '+selector;
};
// Creates an event handler for interpreting "escape", "return", and "blur"
// on a text field and calling "ok" or "cancel" callbacks.
var make_okcancel_handler = function (options) {
var ok = options.ok || function () {};
var cancel = options.cancel || function () {};
return function (evt) {
if (evt.type === "keydown" && evt.which === 27) {
// escape = cancel
cancel.call(this, evt);
} else if (evt.type === "keyup" && evt.which === 13) {
// blur/return/enter = ok/submit if non-empty
var value = String(evt.target.value || "");
if (value)
ok.call(this, value, evt);
else
cancel.call(this, evt);
}
};
};
Template.contents.events = {};
Template.contents.events[okcancel_events('#password')] = make_okcancel_handler({
ok: function (text, event){
var usernameEntry = document.getElementById('username');
var passwordEntry = document.getElementById('password');
Meteor.loginWithPassword({usernameEntry, passwordEntry});
event.target.value = "";
}
});
to the client doesn't work...

Resources