I'm trying to display profile images in a list of users. The list populates all names correctly however I'm having trouble displaying the profile images. The profile images have a separate collection and they're being stored using slingshot S3. The collection is publishing correctly because I can see all the data using meteortoys:allthings. I assume it my js file or how I'm trying to access them in the template. Let me know if you need more info.
Path: userList.js
Template.userList.helpers({
userList: ()=> {
return Meteor.users.find({_id: { $ne: Meteor.userId() }});
},
profileImg: function(){
return Files.find({userId: this._id});
}
});
Path: userList.html
<template name="userList">
{{#each userList}}
{{#if profileImg url}}
<img src="{{url}}" alt="{{url}}" class="profileImg">
{{/if}}
{{profile.firstName}} {{profile.familyName}}
{{/each}}
</template>
userList.js
Template.userList.helpers({
userList() {
return Meteor.users.find({ _id: { $ne: Meteor.userId() } });
},
profileImg() {
return Files.findOne({ userId: this._id });
},
});
userList.html
<template name="userList">
{{#each userList}}
{{#with profileImg}}
<img src="{{url}}" alt="{{url}}" class="profileImg">
{{/with}}
{{profile.firstName}} {{profile.familyName}}
{{/each}}
</template>
The with will change the context for the img such that it actually has a url property. Returning the result of findOne in profileImg is also necessary here.
Related
I have a collection that contains blog posts and I'm trying to get them to display on the page. The code below doesn't list out all the blog posts and I'm not sure why. As far as I can tell it is publishing.
Path: blog.html
{{#each Blog}}
<p>{{details}}</p>
{{/each}}
Path: blog.js
Template.blog.onCreated(function() {
var self = this;
self.autorun(function(){
var id = FlowRouter.getParam('id');
self.subscribe('blog', id);
});
});
Path: Blog mongoDB example
{
"_id": "JvLqxFisXc3PLeqSh",
"details": "Test three",
}
Path: publish.js
Meteor.publish('blog', function (id) {
check(id, String);
return Blog.find({});
});
I need to add a helper.
Template.blog.helpers({
blogPost: ()=> {
return Blog.find({});
}
)}
Path: blog.html
{{#each blogPost}}
<p>{{details}}</p>
{{/each}}
I am having a problem getting my Insert Autoform to work properply. I am trying to have it similar to the example http://autoform.meteor.com/insertaf and my code is below. I have already removed insecure and autopublish
client/templates/venues/venue_submit.html
<template name="venueSubmit">
<!-- {{> quickForm collection="Venues" id="venueSubmit" type="insert"}} -->
{{#if isSuccessfulvenueSubmit }}
<h2>Thanks for the Venue </h2>
{{else}}
{{#autoForm id="insertVenueForm" type="insert" collection=Collections.Venues omitFields="createdAt" resetOnSuccess=true}}
{{> afQuickField name="Venue"}}
<div class="form-group">
<button type="submit" class="btn btn-primary">Add Venue</button>
<button type="reset" class="btn btn-default">Reset Form</button>
</div>
{{/autoForm}}
{{/if}}
</template>
client/templates/venues/venue_submit.js
Schemas = {};
Template.registerHelper("Schemas", Schemas);
Schemas.Venue = new SimpleSchema({
Venue: {
type: String,
label: "Venue Name",
max: 200,
autoform: {
placeholder: "Name of the Venue"
}
},
....
});
AutoForm.debug()
var Collections = {};
Template.registerHelper("Collections", Collections);
Venues = Collections.Venues = new Mongo.Collection("Venues");
Venues.attachSchema(Schemas.Venue);
Venues.allow({
insert: function (userId, doc) {
return true;
},
remove: function (userID, doc, fields, modifier) {
return true;
},
remove: function (userId, doc) {
return true;
}
});
if (Meteor.isClient) {
Meteor.subscribe("Venues")
};
server/Publications.js
Meteor.publish('venue', function () {
return Venues.find(id);
});
The AutoForm insert type generates a document and inserts in on the client. Without the autopublish and insecure packages installed you need to make sure to subscribe to the appropriate collection on the client. It does not exist if you do not subscribe to it.
if (Meteor.isClient) {
Meteor.subscribe("Venues")
}
Your problem is that you have venue_submit.js inside the client folder, but its contents are not intended solely for the client.
You can leave venue_submit.html exactly as it is.
Change venue_submit.js to:
Template.registerHelper("Schemas", Schemas);
AutoForm.debug();
Template.registerHelper("Collections", Collections);
Meteor.subscribe("Venues");
You only need the lines here that relate to the client: the two template helpers, the AutoForm debug (which you don't need except for debugging), and the subscribe to the Venues collection.
Change server/Publications.js to include everything related to the server side:
Meteor.publish('Venues', function () {
return Venues.find({});
});
Venues.allow({
insert: function (userId, doc) {
return true;
},
remove: function (userID, doc, fields, modifier) {
return true;
},
remove: function (userId, doc) {
return true;
}
});
It includes the publish function and the permissions on the collection.
Now create lib/schema.js:
Schemas = {};
Schemas.Venue = new SimpleSchema({
Venue: {
type: String,
label: "Venue Name",
max: 200,
autoform: {
placeholder: "Name of the Venue"
}
}
});
Collections = {};
Venues = Collections.Venues = new Mongo.Collection("Venues");
Venues.attachSchema(Schemas.Venue);
Everything in lib will be available to both the client and server and the contents of this folder will be loaded first so the schema and collection definitions will be available to all the rest of the code. Note the lack of a var keyword for the Collections. Using var sets the scope to only within the file. Omitting it makes the Collections variable available throughout your code.
I'm using Meteor with AutoForm & Iron Router.
I have an autoform for inserting a data, and I want to redirect to the page of the data I added after a successful insert. How should I do it?
Here is the For:
{{#autoForm collection="Products" id="add" type="insert"}}
<h4 class="ui dividing header">Products Information</h4>
{{> afQuickField name='name'}}
{{> afQuickField name='info'}}
<button type="submit" class="ui button">Insert</button>
{{/autoForm}}
Iron Router:
Router.route('/products/:_id', {
name: 'page',
data: function() { return Products.findOne(this.params._id);}
});
Callbacks/Hooks
AutoForm.hooks({
add: {
onSuccess: function(doc) {
Router.go('page', ???);
}
}
});
The AutoForm hook will return you the docId. See:
https://github.com/aldeed/meteor-autoform#callbackshooks
this.docId: The _id attribute of the doc attached to the form, if
there is one, or for an type='insert' form, the _id of the newly
inserted doc, if one has been inserted.
So use:
Router.go('page',{_id: this.docId});
According to the doc on github, signatures changed:
don't forget to declare the forms or null to apply the hooks.
for all forms
AutoForm.addHooks(null,{
onSuccess: function(formType, result) {
Router.go('page',{_id: this.docId});
}
});
for specific form
AutoForm.addHooks(['yourForm'],{
onSuccess: function(formType, result) {
Router.go('page',{_id: this.docId});
}
});
Best is to check the up to date signatures: https://github.com/aldeed/meteor-autoform#callbackshooks
onSuccess: function(formType, result) {
Router.go(
['adminDashboard', result, 'Edit'].join(''),
{_id: this.docId}
);
},
I have a user index and would like to display information on each user. User ID shows up fine, but the app isn't showing emails.
Here is my template:
<template name="users">
<h1>List of all users</h1>
{{#each users}}
<div class="list_item">
<p>ID: {{_id}}</p>
<p>Email: {{email}}</p>
</div>
{{/each}}
</template>
And here are my routes:
Router.route('/users', function () {
this.render('users');
}, {
waitOn: function() {
return [
Meteor.subscribe('users')
]
},
data: {users: Meteor.users.find({})}
});
And finally, my publication:
Meteor.publish('users', function () {
return Meteor.users.find({}, {fields: {emails: 1, profile: 1}});
});
Any ideas?
The correct way to display the email would be :
<p>Email: {{emails.[0].address}}</p>
Email addresses are stored as an array in the user object.
You can check by typing Meteor.user() in the console :
Object {
...
emails: Array[1]
0: Object{
address: "username#domain.com",
verified: false
}
...
}
{{ currentUser.emails.[0].address }}
I have a template helper called notifications and I want to return 3 collection cursors to my template, so that I can view all
Template
<ul class="dropdown-menu notification">
{{#if notificationCount}}
{{#each notifications}}
{{> notification}}
{{/each}}
{{else}}
<li><span>No Notifications</span></li>
{{/if}}
</ul>
Helper
notifications: function() {
if (Meteor.user()) {
var accepted = Notifications.find({ origin: Meteor.user().username, status: 'ACCEPTED' });
var denied = Notifications.find({ rival: Meteor.user().username, status: 'DENIED' });
var confirmed = Notifications.find({ rival: Meteor.user().username, status: 'CONFIRMED' });
return accepted, denied, confirmed;
}
}
What is the best way to go about this? Thanks!
The literal answer to your question is to run fetch on all of the cursors and concatenate them into a single array.
return accepted.fetch().concat(denied.fetch(), confirmed.fetch());
Because all of your documents come from a single collection, you can alternatively use a more sophisticated query. Give this a try:
var username = Meteor.user().username;
return Notifications.find({
$or: [
{
origin: username,
status: 'ACCEPTED'
}, {
rival: username,
status: {$in: ['DENIED', 'CONFIRMED']}
}
]
});