Modifying records with helpers - meteor

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;

Related

Meteor publications/subscriptions not working as expected

I have two publications.
The first pub implements a search. This search in particular.
/* publications.js */
Meteor.publish('patients.appointments.search', function (search) {
check(search, Match.OneOf(String, null, undefined));
var query = {},
projection = {
limit: 10,
sort: { 'profile.surname': 1 } };
if (search) {
var regex = new RegExp( search, 'i' );
query = {
$or: [
{'profile.first_name': regex},
{'profile.middle_name': regex},
{'profile.surname': regex}
]
};
projection.limit = 20;
}
return Patients.find(query, projection);
});
The second one basically returns some fields
/* publications.js */
Meteor.publish('patients.appointments', function () {
return Patients.find({}, {fields: {'profile.first_name': 1,
'profile.middle_name': 1,
'profile.surname': 1});
});
I've subscribed to each publication like so:
/* appointments.js */
Template.appointmentNewPatientSearch.onCreated(function () {
var template = Template.instance();
template.searchQuery = new ReactiveVar();
template.searching = new ReactiveVar(false);
template.autorun(function () {
template.subscribe('patients.appointments.search', template.searchQuery.get(), function () {
setTimeout(function () {
template.searching.set(false);
}, 300);
});
});
});
Template.appointmentNewPatientName.onCreated(function () {
this.subscribe('patients.appointments');
});
So here's my problem: When I use the second subscription (to appointments.patients), the first one doesn't work. When I comment the second subscription, the first one works again. I'm not sure what I'm doing wrong here.
The issue here is you have two sets of publications for the same Collection. So when you refer to the collection in client there is now way to specify which one of the publication it has to refer too.
What you can do is, publish all data collectively i.e. all fields you are going to need and then use code on client to perform queries on them.
Alternatively, the better approach will be to have two templates. A descriptive code:
<template name="template1">
//Code here
{{> template2}} //include template 2 here
</template>
<template name="template2">
//Code for template 2
</template>
Now, subscribe for one publication to template one and do the stuff there. Subscribe to second publication to template 2.
In the main template (template1) include template2 in it using the handlebar syntax {{> template2}}

Meteor template helper to check if a document exists

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()});

What is the best way of fetching data from server in Meteorjs?

I am making simple application where user can add some data in the website. Every time, when user adds new 'name' I want display the latest name automatically for every connected users.
I am not sure if my implementation of Template.names.name is a good idea, maybe I should use subscribe instead?
Here is my code:
<template name="names">
<p>What is your name ?</p>
<input type="text" id="newName"/>
<input type="button" id="nameSubmit" value="add new"/>
<p>Your name: {{name}}</p>
</template>
if (Meteor.isClient) {
Template.names.name({
'click input#nameSubmit': function () {
Meteor.call('newName', document.getElementById("newName").value);
}
});
Template.names.name = function () {
var obj = Names.find({}, {sort: {"date": -1}}).fetch()[0];
return obj.name;
};
}
if (Meteor.isServer) {
newName: function (doc) {
var id = Names.insert({
'name': doc,
'date': new Date()
});
return id;
}
}
I use meteorjs version 0.8.1.1.
The only thing I see inherently wrong with your code is your method.. To define methods you can use with Meteor.call you have you create them with a call to Meteor.methods
Meteor.methods({
newName: function (name) {
Names.insert({
'name': doc,
'date': new Date()
});
}
});
Another couple notes.. The Method should be defined in shared space, not just on the server unless there is some specific reason. That why it will be simulated on the client and produce proper latency compensation.
Also in your Template.names.name you can return the result of a findOne instead of using a fetch() on the cursor.
Template.names.name = function () {
return Names.findOne({}, {sort: {"date": -1}}).name;
};

Meteor.renderList alway end up in [elseFunc]

I'm new to Meteor.
Trying to render items from collection but Meteor.renderList(observable, docFunc, [elseFunc]) alway go to elseFunc.
this.ComponentViewOrdersFlow = Backbone.View.extend({
template: null,
initialize: function() {
var frag;
Template.ordersFlow.events = {
"click a": function(e) {
return App.router.aReplace(e);
}
};
this.template = Meteor.render(function() {
return Template.ordersFlow();
});
console.log(Colors);
frag = Meteor.renderList(
Colors.find(),
function(color) {
console.log(color);
},
function() {
console.log('else consdition');
}
);
},
render: function() {
this.$el.html(this.template);
return this;
}
});
Initially I thought that Collection is empty, but console.log(Colors) shows that there are items in collection. Moreover if I use Meteor.render(... -> Template.colors({colors: Colors.find()}) ) it renders template end show Collection items there.
Meteor version 0.6.6.3 (Windows 7, 64bit)
Mongo - connected to MongoLab
Thank you for any help.
Jev.
Can't really explain this well in the comments, so here is a very, very simple example of using the Meteor template engine. This is a 100% functional app, showcasing basic reactivity. Note that I never call render() or renderList() anywhere.
All this app does is show a button, that when clicked, adds a number to a list. The number is reactively added to the list, even though I never do anything to make that reactivity explicit. Meteor's templates are automatically reactive! Try it out - this is all of the code.
numbers.html:
<body>
{{> numberList}}
</body>
<template name="numberList">
<ul>
{{#each numbers}}
<li>{{number}}</li>
{{/each}}
</ul>
<button>Click Me</button>
</template>
numbers.js:
var Numbers = new Meteor.Collection("numbers");
if (Meteor.isClient) {
Template.numberList.numbers = function() {
return Numbers.find();
};
var idx = 0;
Template.numberList.events({
"click button": function() {
Numbers.insert({
number: idx
});
idx++;
}
});
}

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