Meteor Cheatsheet Ddp Methods
// Meteor - DDP methods:
Methods should be defined in a common place such that they are accessible
on both the client side and the server side. We should keep DDP methods
inside the imports/methods folder, and import these files into the client/main.js
and server/main.js file. The reason why we should make DDP methods accessible
to both client-side and server-side code is due to optimistic UI. On the client-side,
Meteor will invoke the DDP method, which insert or update the Mini-mongo
database on the client-side, which in-turn update the reactive cursors, which
update the UI, assuming that everything will be fine on the server-side. After that,
Meteor execute the same DDP method on the server-side, which insert or update
the server-side Mongo database, which then update those server-side reactive
cursor or publication, which then push the data back to the client-side Mini-mongo
database. If everything is ok on the server side, the Meteor does not need to
rollback its previous client-side operation. If there was a problem on the server-
side, Meteor rollback its previous client-side operation.
Meteor.methods({
moduleInsert: function(moduleAttributes) {
var latestPosition, module, moduleId, moduleWithSameTitle, user;
check(Meteor.userId(), String); // Make sure we are logged in
// Check the types of our attributes, along with the fact they exist
check(moduleAttributes, {
title: String,
body: String,
tags: Array
});
// Here I check if the title is already taken
user = Meteor.user();
moduleWithSameTitle = Modules.findOne({
title: moduleAttributes.title,
userId: user._id
});
// I could probably return an error here
if (moduleWithSameTitle) {
return {
moduleExists: true,
_id: moduleWithSameTitle._id
};
}
// Here I add extra attributes to the ones submitted from client.
// In practice you'll mostly be adding a date for createdAt or updatedAt
module = _.extend(moduleAttributes, {
createdAt: newDate(),
userId: user._id,
author: user.username
});
// Actual insertion into db
return Modules.insert(module);
}
});
// To invoke DDP method, use the Meteor.call method:
Template.moduleSubmit.events({
'submit form': function(e) {
e.preventDefault();
var module = {
title: $(e.target).find('[name=title]').val(),
body: $(e.target).find('#body').val(),
tags: $(e.target).find('select.chosen-select').val()
};
if (module.tags === null) {
module.tags = [];
}
Meteor.call('moduleInsert', module, function(error, result) {
if (error) {
alert(error.reason);
}
if (result.moduleExists) {
alert('This title has already been posted: ' + result._id);
}
Router.go('modulesList', {
username: Meteor.user().username
});
});
}
});
// To use the check module:
Anywhere: check(value, pattern)
Anywhere: Match.test(value, pattern)
# patterns: Match.Any, String, Number, Boolean, undefined, null, Match.Integer, [pattern],
# {key1: pattern1, key2: pattern2, ...}, Match.ObjectIncluding({key1: pattern1, key2: pattern2, ...}),
# Object, Match.Optional(pattern), Match.OneOf(pattern1, pattern2, ...),
# Any constructor function (eg, Date), Match.Where(condition)
page revision: 2, last edited: 18 Jun 2017 02:58