I'm fairly new to meteor and am trying to figure out how to go about creating a user profile page that can be seen by other users and edited by the owner. In my current app the packages that I'm currently using for accounts are accounts-password, useraccounts:materialize, and useraccounts:iron-routing.
I have a page set up already for the profile but can't figure out how to get the data there. I've found other "tutorials" and guides but none clearly point out what I'm aiming to accomplish.
Any help is greatly appreciated.
One easy and recommended way to accomplish this task would be creating a helper for profile and then displaying those data in the blaze. the logged in user's data is published by default. what you can do is something like below
Template.templateName.helpers({
userData : function(){ return Meteor.user() };
});
and then in the blaze use this helper
{{#with userData}}
Name: {{profile.name}}
... rest of the data here.
{{/with}}
Related
I have two pages/Template,
Dashboard (contains some User specific data as well).
Users.
I am using Meteor 1.5 with Blaze Template. Landing Page is Dashboard. I am using the common subscription for Collection Users in both Templates.
Scenario 1
When I use Meteor.subscribe('Users') in Dashboard's template.onCreated() and go to Users page, I see some already subscribed data coming back from Dashboard's subscription.
CODE:
Template.DashBoard.onCreated(function(){
Meteor.subscribe('Users');
});
Template.Users.onCreated(function(){
Meteor.subscribe('Users');
});
Scenario 2
When I use this.subscribe('Users') in Dashboard's template.onCreated() and go to Users page, I get a Fresh Subscription happening here and no data carry over from Dashboard's subscription.
CODE:
Template.DashBoard.onCreated(function(){
this.subscribe('Users');
});
Template.Users.onCreated(function(){
this.subscribe('Users');
});
Question
What is the difference between Meteor.subscribe('Users') and this.subscribe('Users') ? What can be the impact of using this.subscribe('Users') ?
As explained in Meteor documentation, this.subscribe within Template code will be automatically unsubscribed when the template instance is destroyed.
Whereas Meteor.subscribe needs to be explicitly unsubscribed if you want it to.
The decision to use one or the other depends on your app structure. If you are sure the data is relevant only for a given template, then use template scoped subscription, i.e. this.subscribe.
If the data is used across several pages, either use the "global" form, or scoped at a higher template level (one that persists through your pages, e.g. on layout).
When a person signs up (accounts entry) it takes them to a page called "dashboard". I want it so that after they sign-up if it is the first time (for that account) that they are seeing the page it will show some sort of welcome message. Is this possible?
Thanks.
Update:
I tried this:
Accounts.onCreateUser(function(options, user) {
console.log('New account created!');
});
But it gave:
Exception while invoking method 'entryCreateUser' Error: insert requires an argument
I am using Accounts Entry. Is there any fix for this?
Without knowing more about your app it's difficult to advise on the best way for you to do this. But here are three possible approaches.
If you are creating your own signup/login events, just route to a 'welcome' route/template on signup event, and 'dashboard route/template on login.
If you are wanting to use default accounts-ui, you can use the Accounts.onCreateUser hook server side to add {'isNewUser' : true} to the user account document. Then check for this property client side to decide what template to display.
Or you can try wrapping Accounts.createUser to include the extra logic you require client side to go to your welcome route/template rather than the dashboard.
The simplest way is to set a session variable then use a helper in your template to key off of that:
In your new account code:
Session.set('isNewUser',true);
Router.go('dashboard')
HTML:
<template name='dashboard'>
{{#if newUser}}Welcome!!{{/if}
... rest of your template ...
</template>
js:
Template.dashboard.helpers({
newUser: function(){
return Session.get('isNewUser');
}
});
You'll also need code to later either delete that Session variable or set it to false.
Every time a user visits a specific route, I'd like for a new document to get created that will act as a "draft" that the user will edit until they decide to publish it.
Another way to think about this is that I want to redirect a user to a new page displaying the document after a successful insert of the document.
When I phrase it like that, I think I've basically answered my own question. In this case I would just call a Meteor method that creates and inserts the new document, then in the callback method I would use iron-router's Router.go method to redirect to the url using the new _id as a parameter. Is there a better way?
It's a bad idea to get collection created automatically upon visiting a route. What happen if user visit the route unintentionally?
Nevertheless, you can achieve it by inserting a document on publish function and it will get created upon Meteor.subscribe.
Meteor.publish('test-draft', function(options){
var _id = Test.insert({a: 'b'});
return Test.find({_id: _id})
})
If I understand what you're doing correctly, I think the easiest thing would be to just create an object and put it in a Session variable and not mess with creating a document in a collection until you're done editing it.
You can create the object and stick it into Session in Templates.myTemplate.rendered = function() { ... }. And then when it's been satisfactorily edited and submitted pass the Session variable to a Method that inserts it as a new document.
I have an app I am working on that has one or two "main" accounts linked to other accounts. I am using accounts-password, accounts-google, and alanning:roles currently, but I may add other OAuth providers later.
The idea is that there will be one or two users that are "admins" for a larger group, and as such I'd like to be able to allow them to add users. I don't mind if I have to go through the OAuth authorization page on first login, but I would like to be able to add the users to the Meteor.users collection and allow the admins to set things up prior to their logging in, but I am not sure how to do it at all. Can I simply add a user to the Meteor.users collection with only the email attribute of the google sub-document populated? I would guess that the email is NOT what Meteor uses to connect a stored Meteor.users document to the corresponding Google OAuth account as there is also an id attribute that seems like it might be more useful for that purpose.
So based on what you say on the comment i elaborate this DEMO, since you want to create users and add that users to some kind of "role" or "group" im using here the meteor-roles package.
allow people to create a group of users
This could be done on some differentes ways, for the demo purpose im creating 1x1 user and leater assign them a Role.
to avoid the autologin behavior you should use a Meteor.method.
//server
Meteor.methods({
createSimpleUser:function(email){
return Accounts.createUser({
email:email,
password:"test123" //you can force the user in the first login to change the password.
})
}
})
//Client
Meteor.call('createUser',"test#gmail.com")
Now that you have the user created, you should assign them a role.
So on some event handler you want,do something like this.
//this should be incide an {{#each}} or {{#with}} in order to this._id works, if not use Sessions
Meteor.users.update({_id:this._id},{$set:{group:newGroup}})
This is just the global idea, you should protect in the allow rules, who can edit the users group, you can also use template helpers like
{{if userIsInRole 'nameGroup'}}
<!-- Show content only available to users in this group -->
{{else}}
<!-- Some warning access denied template -->
{{/if}}
This process will add some stuff to the profile of the user so the app
can associate all the users together
Filter by groups.
Template.example.helpers({
groupX:function(){
return Meteor.users.find({group:"X"})
}
})
when they first login without erasing the stuff I setup for them prior
to them signing in.
Here again there could be many reasons, for example you can add some field inside the current user created.
Meteor.methods({
createSimpleUser:function(email){
return Accounts.createUser({
email:email,
password:"test123",
firstLogin:false //by default the users login is false.
})
}
})
and in the iron route, create a function(why on the router? see Overworked helpers on the David Weldon webpage).
requireEdit = function(){
var query = Meteor.users.findOne({_id:this.params._id})
if(query.firstLogin == false){
this.render('profileEditin') //do some change password here and other stuff
}else{
this.next()'
}
}
And call it on the onBeforeAction() method
This is just the idea and demo is a ugly-fast example of how it should work, good luck
I doing the following. Adding the current users id as userId in a collection as the author. I would like to be able to access other information in that users (not necessarily the logged in users but could be) so that I could display a profile page. The only work around I have found is to just duplicate the fields from the profile and place them in the collection.
This seems to be less than ideal. Is there a way to access this directly? I am using autopublish so I don't think there should be any permission issues. I am also using iron-router so ideally I would have a route set up like:
Router.map(function() {
...
this.route('profile', {path: '/profile', data: function() { this.params._id}});
});
If you've got autopublish on, then Meteor.users.findOne({_id: 'USERID'}) will give you that user's profile. Obviously, if you turn off autopublish you'll have to work out what information to publish.