Meteor Cheatsheet Ddp Methods

meteor-cheat-sheet

// 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)
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License