Meteor template helper to check if a document exists - meteor

I want to register a helper that i can use in the templates to check if a document exists.
I check if a document exists like this
var selector = {
userid: "3R2pKdT3x9PjWLsD8",
};;
var this_exists = Af.find(selector, {limit: 1}).count() > 0;
I am trying to register a helper like this
Template.registerHelper('ex', function() {
var selector = {
userid: "3R2pKdT3x9PjWLsD8",
};
var this_exists = Af.find(selector, {limit: 1}).count() > 0;
if(this_exists == true) {
return true;
} else {
return false;
}
});
and use it like this in my tempates
{{#if ex}}
{{> quickForm collection="Af" doc=cdoc id="updateSettings" omitFields="userid" class="settings" type="update" buttonContent="Update Settings"}}
{{else}}
{{> quickForm collection="Af" doc=this id="updateSettings" omitFields="userid" class="settings" type="insert" buttonContent="Insert Settings"}}
{{/if}}
but this does not work. Where am i going wrong?.

If this doesn't solve your problem, then there might a problem with your pub/sub.
You don't need limit. Instead use findOne and you don't need to check the count.
var exists = Af.findOne({userId: "3R2pKdT3x9PjWLsD8"}); //be careful with userId here, as it might be userid in your codes.
If(exists){
return true;
} //we don't need else block here. Your html if else block will work fine with this.
Additionally, if the userId you use is current user's id, you can use Meteor.userId()
var exists = Af.findOne({userId: Meteor.userId()});

Related

Meteor How to call global helper in template file?

I have created global helper in app/client/lib/global_helper.js
Template.registerHelper("getImages", id => {
if(id){
let user = Meteor.users.findOne({_id: id});
try {
if (user.profile.picture) {
return user.profile.picture;
} else {
return "http://api.adorable.io/avatars/150/"+id+".png";
}
}catch(e) {
return "http://api.adorable.io/avatars/150/"+id+".png";
}
}
});
and trying to call it in my html template
app/client/template/shared/sidebar/my_sidebar.html
<img src="{{getImages this._id}}" alt="User" class="profilepic">
But it's not working. Not getting what is issue.
It's working when i called it in other files
app/client/template/pages/dashboard/dashboard.html
If your console is working properly then you should try ES6 way as like id instead of _id: id see the below
let user = Meteor.users.findOne({ id });

Getting Data from Server side HTTP.call to Client template

I currently use meteor for a microproject of mine to get a bit usage experience with it. Shortly after setting up I ran into some trouble getting Data i recieve from an API call to a third party site to the client into the template. I checked the usual places for answers and found some information but nothing seems to get it working for me.
So I have a simple API Call to the Steam Web Api:
Meteor.methods({
getPlayerStats: function() {
return HTTP.get("http://api.steampowered.com/ISteamUserStats/GetUserStatsForGame/v0002/?appid=730&key=XXXXXXXXXXXXXXX&steamid=XXXXXXXX");
}
});
(Api key and steam id removed for anonymity purpose, but the call indeed returns a valid response)
So I use Iron Router for template rendering.
Router.route('/profile/:steamid', {
name:'profile',
template: 'profile',
data: function() {
Meteor.call('getPlayerStats', function(err, res) {
if(err) {
return {err: err, stat: null};
} else {
var redata = JSON.parse(res.content);
var stats = redata.playerstats.stats;
console.log({err: null, stats: stats});
return {err: null, stats: stats};
}
});
}
});
So as you can see i return an object in the data method containing either err or a parsed version of the result i get from the api call. The console.log actually returns everything as intended in the client browser, that is an object like this:
{err: null, stats: [{name: "xx", value: "XY"},...]}
And now the part that actually gets me wondering, the template:
<template name="profile">
<p>{{err}}</p>
<ul>
{{#each stats}}
<li>{{name}} - {{value}}</li>
{{/each}}
</ul>
</template>
Which fails to render anything, not the err (which is null and therefor not very important) but neither the stats array.
Anyone has any idea where I went wrong on this one?
You cannot return data from asynchronous call. Instead, You can do it in the template's created function by using ReactiveVar or Session Variable like this
Template.profile.created = function () {
// or Template.profile.onCreated(function () {
var template = this;
template.externalData = new ReactiveVar(null);
Meteor.call('getPlayerStats', function(err, res) {
if(err) {
template.externalData.set({err: err, stat: null});
} else {
var redata = JSON.parse(res.content);
var stats = redata.playerstats.stats;
console.log({err: null, stats: stats});
template.externalData.set({err: null, stat: stats});
}
});
};
// }); //comment the above line and use this, if you used onCreated instead of created.
Then in your helpers,
Template.profile.helpers({
externalData: function () {
var template = Template.instance();
return template.externalData.get();
}
});
Then in your template html,
<template name="profile">
{{#if externalData}}
{{#if externalData.err}}
<p>There is an error. {{externalData.err}}</p>
{{else}}
<ul>
{{#each externalData.stats}}
<li>{{name}} - {{value}}</li>
{{/each}}
</ul>
{{/if}}
{{/if}}
</template>

How to make global helper that returns users profile name?

How to make register helper that returns users profile name?
I want to make a global template helper that would show a users profile name in the view. So, the use case would be I have one template that list items, another for messages and another lastly displaying the item on its own page. This is what I have so far:
client/helpers.js
// if we used items as a example, make its so the item template can see the specific item.
Template.items.helpers({
items: function() {
return Items.find();
},
});
Template.registerHelper("usernameFromId", function (userId) {
var user = Meteor.users.findOne({_id: userId});
return user.profile.name;
});
client/subscriptions.js
Meteor.subscribe('allUsernames');
server/publications.js
Meteor.publish("allUsernames", function () {
return Meteor.users.find({},
{ fields: { 'profile.name': 1 }
});
});
client/templates/item.html
<template name="item">
{{usernameFromId user}}
</template>
This does nothing, where am I in error?
UPDATE
No changes yet, as I'm not sure what to do.
The code is actually correct. In order to make the global helper I had to change:
var user = Meteor.users.findOne({_id: userId});
to
var user = Meteor.users.findOne({_id: this.userId});
So the complete function is:
Template.registerHelper("usernameFromId", function (userId) {
var user = Meteor.users.findOne({_id: this.userId});
return user.profile.name;
});
Thanks commentators!

Modifying records with helpers

Is it possible to modify a record with helpers?
Example: (_id: "CbQvD52iEFXnFML3d", name:"somename", age:"20", video:"stack.com/link.mp4").
I would like to modify all the records found before they are sent to the template.
Records= new Meteor.Collection('records');
Template.test.helpers({
record: function() {
var info = Records.find({age:"20"});
//modify all records found from "stack.com/link.mp4" to "stack.com/link.jpg"
return collection with modified records
}
});
<template name="test">
{{#each record}}
{{name}}
<img src="{{video}}">
{{/each}}
</template>
Thanks!
Yes. You can apply a transform to either a particular find or to the entire collection. In this example we'll add the transform only to the find used in the record helper:
var transform = function(doc) {
doc.video.replace(/mp4$/, 'jpg');
return doc;
};
Template.test.helpers({
record: function() {
return Records.find({age: '20'}, {transform: transform});
}
});
var recordsArray = Records.find({age:"20"}).fetch();
recordArray.forEach( function (entry) {
entry.video = "stack.com/link.jpg";
}
return recordsArray;
*Note this will not update the collections video. It will only change the video for the array;

Meteor - How to insert dynamically generated content into a collection?

I'm new to Meteor and barely understand any of it but let's say I have a collection called mycollection, declared way up top so it's available in both the client and server section:
mycollection = new Meteor.Collection('MyDumbCollection');
And then I have something like this:
if (Meteor.isClient) {
Deps.autorun(function() {
Meteor.subscribe('mycollectionSubscription');
});
Template.myshittytemplate.rendered = function() {
$("#heynow").prepend(shitfuck).dosomething();
godammit = thisfuckingthing;
//paraphrasing
mycollection.insert({thing1: thisfuckingthing});
};
}
if (Meteor.isServer) {
Meteor.publish('mycollectionSubscription', function () {
return mycollection.find();
});
};
And then in my template:
<template name="myshittytemplate">
<div id ="heynow">
{{#each mycollection}}
{{{thing1}}}
{{/each}}
</div>
</template>
What I'm trying to do is have the 'thisfuckingthing' html that's created in the #heynow div saved to the collection and published to everybody. If there's a way to make Meteor simply observe changes to the dom and save them, that's even better.
I do have autopublish uninstalled, if that makes a difference. Halp.
In client Template
Template.myshittytemplate.mycollection = function() {
return mycollection.find({}).fetch();
};
Template.myshittytemplate.rendered = function() {
$(function(){
$("#heynow").prepend(shitfuck).dosomething();
godammit = thisfuckingthing;
//paraphrasing
mycollection.insert({thing1: thisfuckingthing},function(err,_id){
if(err){
console.log(err);
return;
});
console.log(_id);
});
};
}
I needed this in the Client part:
Template.myshittytemplate.mycollection = function() {
return mycollection.find();
};
Hopes this helps somebody!

Resources