Meteor website delay to identify {{currentuser}} - meteor

I am new to Meteor. What I want is when I go to the page if the user is logged in, show "Logged In" and if not show "Not Logged In", here the is snippet I tried that,
{{#if currentUser}} Logged In {{else}} Not Logged In {{/if}}
So when a "signed up" user comes I expect, directly showing "Logged In". But what happen is it shows "Not Logged In" first and then after about a second shows "Logged In". How to avoid this?
Thanks in advance

That's because the user is still logging in. I recommend you define a helper as such:
Template.myTemplateName.helpers({
authenticated: function() {
return Meteor.user() || Meteor.loggingIn();
}
})
and then use it like you want:
{{#if authenticated}} Logged In {{else}} Not Logged In {{/if}}

Related

Wait for Meteor.user() to completely load before template renders

This has been asked before however, I don't feel I've seen a suitable answer. I'm currently using {{ #if currentUser.emails.[0].verified }} show data {{else}} please verify email {{/if}} on the layout template check whether or not the user has verified their email. In this scenario, I get a flicker between the screens if the user has registered because meteor.user() hasn't loaded completely so currentUser.emails.[0].verified returns null and changes to true once it has loaded completely.
Is there a way I can wait for Meteor.userId to completely load before the template renders without using delay?
The meteor embedded "currentUser" helper can let you know when the user collection is ready:
{{#if currentUser}}
// Do my stuff
{{else}}
Checking... // You can also show a spinner image or GIF here
{{/if}}
You can force the Template.subscriptionsReady to wait for the Meteor.user() data (so that when the Template.subscriptionsReady is true, the currentUser logic is also up-to-date and won't change) by adding a stub subscription.
I added the following Subscription and then subscribed to this from the template:
Meteor.publish('userWait', function () {
return null;
});
Here's a more detailed description of why this issue was popping up:
When loading a template, if you're only relying native handler for currentUser - then currentUser will always initially load false (in the template logic) and then will load true once the data load is complete.
Adding logic to show a loading state that relies on Template.subscriptionsReady will only work if there is an additional Subscription for the template (Template.subscriptionsReady doesn't acknowledge the automatic subscriptions for the user data).
For me, this meant that the internal pages will always prompt a login before realizing that the user was already logged in ... which was an ugly UX.
Once I added a Subscription to the template, even though it returned nothing, then Template.subscriptionsReady would wait until Meteor.user() data was available before returning as true.
Typically, you can use Template.subscriptionsReady in your Template to wrap code that depends upon subscribed data. Since Meteor handles the publish/subscribe of currentUser automatically, I'm not sure if this method will work or not. Give it a try and let me know.
Example.
{{#if Template.subscriptionsReady}}
{{ #if currentUser.emails.[0].verified }} show data {{else}} please verify email {{/if}}
{{/if}}
What I have found to work well for me is to subscribe to the user in the wait in a waitOn function in iron router:
Router.route('/',{
waitOn: [
function() {
if (!Meteor.userId()) {
Router.go("/login");
}
return Meteor.subscribe('currUser');
},
],
...
})

Display twitter name and avatar in meteor app

Im building and app using meteor and ionic and i want to display the name and the avatar of the user logged in.
I wrote this
<img src="{{Meteor.users().services.twitter.profile_image_url}}">
but it is not working. The same query in my console returns the right result. Is it becaus i removed autopublish ? Is there a way to overcome this?
Define a helper then use it for the URL
Template.templateName.helpers({
imageUrl: function(){
return Meteor.user().services.twitter.profile_image_url;
//you wrote Meteor.users() which should be user()
}
});
Then use it in your HTML
<img src="{{imageUrl}}">
EDIT:
Meteor.user() will return the current user object. If you want the user's profile picture to be visible somewhere to other users or even if that user is not logged in, you should store user's id and use that id to find & return user object or some specific data. For example, if you have a posts collection, you can do the following...
//inside your insert post method, save userId
owner: this.userId
//usage in template helper where you have the post data
userObj: function(){
return Meteor.users.findOne(this.owner) //returns user object.
}
//HTML
{{userObj.someData}}
To overcome removal of autopublish you can publish your collection data in a server javascript file and subscribe to same collection in a client javascript file.
Also you can do the following for your own image collections, better implementation in my point of view:
in a HTML file where you get your userId from router:
<img src="{{getUserProfileImage userId}}">
in a client javascript file like common.js
Template.registerHelper('getUserProfileImage', function(userId) {
return UserImages.findOne({userId: userId}).image;
}
});
You should better store each image in a collection like I did. Also using Meteor.user() directly may cause errors if user hasn't logged-in.
Please add javascript tag to your codes for formatting.

Meteor show objects only if logged in, reactive

I am very new to Meteor, I have a simple problem that can't find a right answer too.
I want to show a component only if they are logged In.
I tried to do it this way
Template.newPost.rendered= function(){
if(Meteor.user()){
$('#submit-btn').show();
$('#submit-text').hide();
}
else{
$('#submit-btn').hide();
$('#submit-text').show();
}
}
but problem is it get rendered before the Meteor.user() get loaded.
I think I am doing this the hard way is there any reactive way to do this simpler? if not, how can I make this approach work?
Thanks
If you are using blaze, you can skip all that and just use the currentuser helper in your template like this:
{{#if currentUser}}
<button id="submit-btn">Click me</button>
{{else}}
<p id="submit-text">Please log in to submit</p>
{{/if}}

Button State Persistence

I have a 'Create Post' button in which a user can use to submit a post. I only want the user to be able to create one post at a time. So the user would have to remove the first post to create another, or they would have to wait for that post to be removed by someone else - which is perfectly acceptable.
Also, I want the button to be disabled when there is already a live post of theirs.
So, basically, what's the best way to attach the state of the button to the state of the post, so that as soon as the post is removed, the button is then enabled.
Thanks.
Fortunately, spacebars makes this really easy to do. Have a look at the "Smarter Attributes" section of this post.
Here is an example:
<template name="post">
<button disabled={{isDisabled}}>Create Post</button>
</template>
Template.post.isDisabled = function () {
return Posts.findOne();
};
In this case the button will be disabled if any posts were found, but you can easily modify that to your specific requirements.

Working with accounts and data

In the next phase of my chat room application I want to work with user accounts.
I want to do the following.
Require user to create an account or login to post a message (when logged out the message area will be replaced with a bootstrap alert box)
Once logged in, the name field will use the username
It would also be nice to allow users to set their username rather than it be their email address.
I have been looking through questions and the parties tutorial but I have not yet been able to reverse engineer the functionality in my instance. Would anyone be willing to assist me?
Project files - https://github.com/SmashBrando/chatroom
Project - http://smashchat.meteor.com/
Answered:
To display content if the user is logged in I added:
{{#if currentUser}}
{{> entry}}
{{else}}
<div class="alert alert-error">
You Must Login To Post a Message!
</div>
{{/if}}
To set the username as the message name (the profile name a user wants to be known as) I added the following code to the input area.
<input type="text" class="span6" id="name" value="{{currentUser.username}}">
I will be working on a future iteration that does not use the input box and uses a variable (once I figure out how to do that).
you can use the handlebars helper and if/else to show certain items
{{#if currentUser}}
<logged in content>
{{else}}
<not logged in content>
{{/if}}
for the user's name, you'll have to use another field for their real name, usually within the profile eg. user.profile.name
assuming the user's name has been set, you should then be able to do something like
{{#if currentUser}}
{{loginButtons}}
{{else}}
{{currentUser.profile.name}}
{{/if}}

Resources