Iterating through user accounts in meteor accounts UI - meteor

I wanted to display all the user information in a tabular format as a part of an admin page. I used meteor accounts ui package for the same.
The HTML code is:
{{#each userList}}
<tbody>
<tr>
<th scope="row">*</th>
<td>{{infofullname}}</td>
<td>{{infosurname}}</td>
<td>{{infoemail}}</td>
</tr>
</tbody>
{{/each}}
The problem is that the information for the current user is getting displayed and not all the enrolled users. The iteration does happen but for the current logged in user. Also the email address is not getting displayed.
The helper code is:
Template.students.helpers({
userList: function(){
return Meteor.users.find({});
},
infofullname: function(){
return Meteor.user().profile.fullname;
},
infosurname: function(){
return Meteor.user().profile.surname;
},
infoemails: function(){
return Meteor.user().emails.[0].address;
}
});
Im facing the following problems:
1) The email address is not getting displayed.
2)The information of all the users is not getting displayed.
Thank You.

Publish all users with the following on the server:
Meteor.publish('allUsers',function(){
return Meteor.users.find({},{fields: {emails: 1, profile: 1}});
this.ready();
});
Then subscribe on the client with:
Meteor.subscribe('allUsers');
Your helpers will need some slight modifications as #Sudhanshu suggested however since you're looping over a cursor of users you can take advantage of this being an individual user object inside the loop.
Template.students.helpers({
userList() {
return Meteor.users.find({});
},
infofullname() {
return this.profile.fullname;
},
infosurname() {
return this.profile.surname;
},
infoemails: function(){
return this.emails.[0].address;
}
});
You can also access nested properties directly in blaze, avoiding the need for three of your helpers, ex:
{{#each userList}}
<tbody>
<tr>
<th scope="row">*</th>
<td>{{profile.fullname}}</td>
<td>{{profile.surname}}</td>
<td>{{emails.[0].address}}</td>
</tr>
</tbody>
{{/each}}

Multiple things are wrong:
Meteor.users() will give you multiple users only if you publish them (or you use autopublish).
Meteor.user() will always give you only the currently logged in user. So all your helpers will not work as per your plan. Modify them to use Meteor.users.findOne({_id: id)}). You can always use helpers with parameters.
Meteor publishes only the profile by default and not the emails. So you will have to publish the emails field in your publication.

Related

How do I control two subscriptions to display within a single template?

Sorry kind of new to the Meteor framework!
I Subscribed to two Publish functions. Even if both publish functions target the same Collection, they both have different functions, that I would like to display in one template. How do I achieve this. I have done allot of research but there doesn't seem to be sufficient information on how to achieve.
Following are the two publish functions in code that I subscribe to:
.server/main.js:
Meteor.publish('MerchantTrending', function (categoryMan){
var currentUser = this.userId;
return buyList.find({ who:"Merchant", ownerId:currentUser, itemCategory: { $in: categoryMan } }, {skip: 0, limit: 3});
});
.server/main.js:
Meteor.publish('myTopViews', function (){
var currentUser = this.userId;
return buyList.find({ newArrivalsExpiryDate : {'$lte': new Date()}}, {ownerId:currentUser }, {skip: 0, limit: 3});
});
Following is the subscription function in code
.client/main.js:
Router.route('/MerchantLandingPage', {
subscriptions: function(){
var categoryMan = Session.get('category');
return Meteor.subscribe('MerchantTrending', categoryMan, 'merchantTopViews')
}
});
Now the helper function in code:
Template.MerchantLandingPage.helpers({
'top3Trending' : function () {
return buyList.find({}).fetch();
},
'myTopViews' : function () {
return buyList.find({}).fetch();
}
});
And now the template in code:
<template name="MerchantLandingPage">
##### *** Top three trending items *** ########
{{#each top3Trending}}
ItemName:: <b>{{itemName}}</b> <br>
Item Category:: <b>{{itemCategory}}</b> <br>
Discription:: <b>{{descriptions}}</b> <br>
Image:: {{this.photo._id}} <br>
Date Created:: {{createdDate}} <br>
{{/each}}
<br><br>
############ *** My top Views *** #############
{{#each myTopViews}}
ItemName:: <b>{{itemName}}</b> <br>
Item Category:: <b>{{itemCategory}}</b> <br>
Discription:: <b>{{descriptions}}</b> <br>
Image:: {{this.photo._id}} <br>
Date Created:: {{createdDate}} <br>
{{/each}}
</template>
Both {{#each myTopViews}} and {{#each top3Trending}} successfully display but not correctly. When the variable categoryMan in
Meteor.subscribe('MerchantTrending', categoryMan, 'merchantTopViews')
changes value, it affects both both the outcome of both {{#each myTopViews}} and {{#each top3Trending}}, when its only supposed to affect {{#each top3Trending}}.
How can I get the subscriptions to NOT have an affect on both {{#each myTopViews}} and {{#each top3Trending}}, but only {{#each myTopViews}} in my template?
Thanks for the help!
Welcome to Meteor!
The solution is straight forward once you understand that:
Subscription is just a stream of your DB documents from server into your client's MiniMongoDB. So your 2 subscriptions (it is perfectly fine having several subs on the same Collection) just fill in your client's buyList local collection.
Use of Collections client side is generally independent from how you subscribe the data. So you should simply use a similar selector and possibly options in your top3Trending and myTopViews helpers as you have done for your publication server side (not the same between the 2 helpers, obviously).
As a side note, you do not even need to fetch() the Collection cursor returned by find(), Blaze knows how to handle it directly.
I see a few problems with your code, first of all - your second subscription isn't going to work because your query is wrong:
Meteor.publish('myTopViews', function (){
var currentUser = this.userId;
return buyList.find(
{ ownerId:currentUser, newArrivalsExpiryDate : {'$lte': new Date()}},
{skip: 0, limit: 3}
);
});
You had ownerId: currentUser wrapped in curly braces, it is fixed above.
The way publications/subscriptions work is, if you have two publications sending different data, the template doesn't 'know' the data is coming from two different subscriptions. It will just have access to all of the data being sent by all subscriptions.
For that reason, your two helpers top3trending and myTopViews are returning exactly the same thing. You can delete one of them!
You should move your subscriptions out of the router and in to the Template itself. Here's an article that will help you with that!
There is a package percolate:find-from-publication that permits to filter the data from publications.

Meteor not displaying data from collection in html

I am trying to get data from a collection in meteor and using a helper passing it to a template.
Here is my code in collection:
Meteor.publish('displayCustomers', function tasksPublication() {
return Customers.find();
});
Below code in template JS file
Template.customerlist.onCreated(function() {
Meteor.subscribe('displayCustomers');
});
Template.customerlist.helpers({
displayCustomers :function(){
console.log(Customers.find({}));
return Customers.find({});
},
});
Template:
<template name="customerlist">
<h1>All registered users</h1>
{{#each displayCustomers}}
{{fname}}
{{/each}}
</template>
It is only displaying HTML content i.e. <h1>All registered users</h1>
Check that your publication is returning values to the client with this MiniMongo chrome extension
Check to make sure Customers is defined on the server and that your publish block is running only on the server.
Also I would toss a debugger into your onCreated block to make sure that your subscribe is being initialized.
Other than that, your code looks fine. I would try installing MeteorToys Mongol for client pub/sub debugging. https://atmospherejs.com/msavin/mongol
You need to actually fetch documents in your template :
Template.customerlist.helpers({
displayCustomers :function(){
return Customers.find().fetch(); //will return an array with all published documents
},
});

Display list of user email addresses in Meteor

I'm trying to get a list of all users in meteor using Metor.methods
This is my code :
server/main.js
Meteor.methods({
'createUser': function(){
if (Meteor.users.find({}).count()===0) {
for (i = 0; i <= 5; i++){
let id = Accounts.createUser({
email: Meteor.settings.ADMIN_USE,
password: Meteor.settings.ADMIN_PASSWORD,
profile: { firstName: Meteor.settings.ADMIN_FIRSTNAME, lastName: Meteor.settings.ADMIN_LASTNAME }
});
}
}
},
'returnmail': function(){
return Meteor.users.findOne().emails[0].address;
}
});
then i call this function in another file called Listusers.js:
Template.ListUsers.helpers({
email: function(){
Meteor.call('returnmail');
},
});
I'm trying to display the value of email using this code but it doesn't work
Client/ListUsers.html
<Template name="ListUsers">
<input id="mail" type="text" value="{{email}}" />
</Template>
Several problems. I strongly recommend you go through the tutorial at least. The Discover Meteor ebook is also invaluable. One of the first steps in understanding Meteor is moving from a traditional XHR request-response model to publish-subscribe.
Your email helper needs to return a value.
Meteor.call() doesn't return anything. Normally you use it with a callback that gives you an error status and the result. However you can't use that in a helper unless you use a Session variable or a promise because the return value from the call is at the wrong context level.
Your returnmail method is only returning a single email address from findOne() and not any specific one either, just a quasi-random one (you can't guarantee which document findOne() is going to return!)
You're creating 5 identical users with the same email address and password. 2-5 are going to fail because of a uniqueness constraint on the email field.
Now on to the solution.
On the server, publish the Users collection including only the emails field (which is an array of objects)
On the client, subscribe to that publication.
On the client, iterate over the users collection and get the email address from a helper.
server:
Meteor.publish('allEmails',function(){
// you should restrict this publication to only be available to admin users
return Meteor.users.find({},{fields: { emails: 1 }});
});
client js:
Meteor.subscribe('allEmails');
Template.ListUsers.helpers({
allUsers(){ return Meteor.users.find({}); },
email(){ return this.emails[0].address; }
});
client html:
<Template name="ListUsers">
{{#each allUsers}}
<input id="mail" type="text" value="{{email}}" />
{{/each}}
</Template>

How can I create a list of online/active users?

I'm using the package mizzao:user-status to add online/active statuses to my users. Using this, I'm able to run a query to get all online users.
The problem I'm facing is, keeping a list of users up to date with users that are logged in.
I believe I would need to use Accounts.onLogin to update the list, which I think is used on the server side. So, how would I keep a list of users up to date with users that are connected on the client side?
Like mizzao point on the README.
First Do the Publish.
Meteor.publish("userStatus", function() {
return Meteor.users.find({ "status.online": true });
});
and the subscribe,
Meteor.subscribe('userStatus')
Second do a helper to return the users online.
Javascript
Template.example.helpers({
usersOnline:function(){
return Meteor.users.find({ "status.online": true })
},
usersOnlineCount:function(){
//event a count of users online too.
return Meteor.users.find({ "status.online": true }).count();
}
})
HTML
<template name="example">
There are currently {{usersOnlineCount}} users online.
<h1>List of Users online </h1>
<ul>
{{#each usersOnline}}
<li> {{username}}</li>
{{/each}}
</ul>
</template>

Meteor Iron:Router Problems Getting ID

Can someone explain why am i getting the full value of ObjectID instead just the clean ID?
This is what i'm getting:
And the HTML output:
My Post
I haven't done anything out of the ordinary. Very basic stuff right now. Just trying out Meteor for the first time.
Routing: lib/router.js
// Dashboard
Router.route('/dashboard', {name: 'dashboard'});
// Post detail
Router.route('/summary/:_id', {
name: 'postSummary',
data: function() {
return Post.findOne(this.params._id);
}
});
List page template: templates/posts/post_dashboard.html
{{#each posts}}
<tr>
<td>
<p>{{title}}</p>
<p><small>Created at {{createdAt}}</small></p>
</td>
...
</tr>
{{/each}}
Detail page template: templates/posts/post_summary.html
<template name="postSummary">
{{> postHeader}}
<h3>{{title}}</h3>
</template>
Template helper: templates/posts/posts.js
Template.dashboard.helpers({
posts: function () {
return Post.find({});
}
});
And here's the packages i have installed, just in case it's necessary.
meteor-platform
autopublish
insecure
matthew:foundation5-sass
iron:router
jquery
useraccounts:core
useraccounts:foundation
accounts-password
accounts-facebook
accounts-google
accounts-ui-unstyled
aldeed:autoform
aldeed:collection2
forwarder:autoform-wizard
fortawesome:fontawesome
When you query the Posts collection from the console, is the _id in the returned document(s) a string literal or an ObjectId Object?
Assuming it's the latter, that's why this is happening, and if so, it's probably going to be because you've populated the collection by using insert in the Mongo shell (or alternatively restored from an existing MongoDB). By default, Meteor insert uses strings for the auto-added id when the id is not specified, whereas Mongo uses ObjectIds.
Hope that helps, but let me know if I'm on totally the wrong track!
Mongo ObjectID has a property: _str It includes string representation of the ID.

Resources