Meteor Guide
The best point to get started with Meteor is the Meteor Guide. From there you can find links to other resources, intructions to install Meteor, and associated content. This is the Meteor API docs, documenting the interface of Meteor's core APIs.
The Meteor API
Your JavaScript code can run in two environments: the client (browser), and the server (a Node.js container on a server). For each function in this API reference, we'll indicate if the function is available just on the client, just on the server, or Anywhere.
Meteor Core
Anywhere
Meteor.isClient
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Boolean variable. True if running in client environment.
Anywhere
Meteor.isServer
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Boolean variable. True if running in server environment.
Meteor.isServer
can be used to limit where code runs, but it does not
prevent code from being sent to the client. Any sensitive code that you
don't want served to the client, such as code containing passwords or
authentication mechanisms, should be kept in the server
directory.
Anywhere
Meteor.isCordova
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Boolean variable. True if running in a Cordova mobile environment.
Anywhere
Meteor.isDevelopment
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Boolean variable. True if running in development environment.
Anywhere
Meteor.isProduction
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Boolean variable. True if running in production environment.
Anywhere
Meteor.startup(func)
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Run code when a client or a server starts.
Arguments
- func Function
-
A function to run on startup.
On a server, the function will run as soon as the server process is
finished starting. On a client, the function will run as soon as the DOM
is ready. Code wrapped in Meteor.startup
always runs after all app
files have loaded, so you should put code here if you want to access
shared variables from other files.
The startup
callbacks are called in the same order as the calls to
Meteor.startup
were made.
On a client, startup
callbacks from packages will be called
first, followed by <body>
templates from your .html
files,
followed by your application code.
// On server startup, if the database is empty, create some initial data.
if (Meteor.isServer) {
Meteor.startup(function () {
if (Rooms.find().count() === 0) {
Rooms.insert({name: "Initial room"});
}
});
}
Anywhere
Meteor.wrapAsync(func, [context])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Wrap a function that takes a callback function as its final parameter. The signature of the callback of the wrapped function should be function(error, result){}
. On the server, the wrapped function can be used either synchronously (without passing a callback) or asynchronously (when a callback is passed). On the client, a callback is always required; errors will be logged if there is no callback. If a callback is provided, the environment captured when the original function was called will be restored in the callback.
Arguments
- func Function
-
A function that takes a callback as its final parameter
- context Object
-
Optional
this
object against which the original function will be invoked
Anywhere
Meteor.defer(func)
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Defer execution of a function to run asynchronously in the background (similar to Meteor.setTimeout(func, 0)
.
Arguments
- func Function
-
The function to run
Anywhere
Meteor.absoluteUrl([path], [options])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Generate an absolute URL pointing to the application. The server reads from the ROOT_URL
environment variable to determine where it is running. This is taken care of automatically for apps deployed to Galaxy, but must be provided when using meteor build
.
Arguments
- path String
-
A path to append to the root URL. Do not include a leading "
/
".
Options
- secure Boolean
-
Create an HTTPS URL.
- replaceLocalhost Boolean
-
Replace localhost with <IP_ADDRESS>. Useful for services that don't recognize localhost as a domain name.
- rootUrl String
-
Override the default ROOT_URL from the server environment. For example: "
http://foo.example.com
"
Anywhere
Meteor.settings
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Meteor.settings
contains deployment-specific configuration options. You can initialize settings by passing the --settings
option (which takes the name of a file containing JSON data) to meteor run
or meteor deploy
. When running your server directly (e.g. from a bundle), you instead specify settings by putting the JSON directly into the METEOR_SETTINGS
environment variable. If the settings object contains a key named public
, then Meteor.settings.public
will be available on the client as well as the server. All other properties of Meteor.settings
are only defined on the server. You can rely on Meteor.settings
and Meteor.settings.public
being defined objects (not undefined) on both client and server even if there are no settings specified. Changes to Meteor.settings.public
at runtime will be picked up by new client connections.
Anywhere
Meteor.release
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Meteor.release
is a string containing the name of the release with which the project was built (for example, "1.2.3"
). It is undefined
if the project was built using a git checkout of Meteor.
Publish and subscribe
These functions control how Meteor servers publish sets of records and how clients can subscribe to those sets.
Server
Meteor.publish(name, func)
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Publish a record set.
Arguments
- name String
-
Name of the record set. If
null
, the set has no name, and the record set is automatically sent to all connected clients. - func Function
-
Function called on the server each time a client subscribes. Inside the function,
this
is the publish handler object, described below. If the client passed arguments tosubscribe
, the function is called with the same arguments.
To publish records to clients, call Meteor.publish
on the server with
two parameters: the name of the record set, and a publish function
that Meteor will call each time a client subscribes to the name.
Publish functions can return a
Collection.Cursor
, in which case Meteor
will publish that cursor's documents to each subscribed client. You can
also return an array of Collection.Cursor
s, in which case Meteor will
publish all of the cursors.
If you return multiple cursors in an array, they currently must all be from different collections. We hope to lift this restriction in a future release.
// server: publish the rooms collection, minus secret info.
Meteor.publish("rooms", function () {
return Rooms.find({}, {fields: {secretInfo: 0}});
});
// ... and publish secret info for rooms where the logged-in user
// is an admin. If the client subscribes to both streams, the records
// are merged together into the same documents in the Rooms collection.
Meteor.publish("adminSecretInfo", function () {
return Rooms.find({admin: this.userId}, {fields: {secretInfo: 1}});
});
// publish dependent documents and simulate joins
Meteor.publish("roomAndMessages", function (roomId) {
check(roomId, String);
return [
Rooms.find({_id: roomId}, {fields: {secretInfo: 0}}),
Messages.find({roomId: roomId})
];
});
Alternatively, a publish function can directly control its published record set
by calling the functions added
(to add a new document to the
published record set), changed
(to change or clear some
fields on a document already in the published record set), and
removed
(to remove documents from the published record
set). These methods are provided by this
in your publish function.
If a publish function does not return a cursor or array of cursors, it is
assumed to be using the low-level added
/changed
/removed
interface, and it
must also call ready
once the initial record set is
complete.
Example:
// server: publish the current size of a collection
Meteor.publish("counts-by-room", function (roomId) {
var self = this;
check(roomId, String);
var count = 0;
var initializing = true;
// observeChanges only returns after the initial `added` callbacks
// have run. Until then, we don't want to send a lot of
// `self.changed()` messages - hence tracking the
// `initializing` state.
var handle = Messages.find({roomId: roomId}).observeChanges({
added: function (id) {
count++;
if (!initializing)
self.changed("counts", roomId, {count: count});
},
removed: function (id) {
count--;
self.changed("counts", roomId, {count: count});
}
// don't care about changed
});
// Instead, we'll send one `self.added()` message right after
// observeChanges has returned, and mark the subscription as
// ready.
initializing = false;
self.added("counts", roomId, {count: count});
self.ready();
// Stop observing the cursor when client unsubs.
// Stopping a subscription automatically takes
// care of sending the client any removed messages.
self.onStop(function () {
handle.stop();
});
});
// client: declare collection to hold count object
Counts = new Mongo.Collection("counts");
// client: subscribe to the count for the current room
Tracker.autorun(function () {
Meteor.subscribe("counts-by-room", Session.get("roomId"));
});
// client: use the new collection
console.log("Current room has " +
Counts.findOne(Session.get("roomId")).count +
" messages.");
// server: sometimes publish a query, sometimes publish nothing
Meteor.publish("secretData", function () {
if (this.userId === 'superuser') {
return SecretData.find();
} else {
// Declare that no data is being published. If you leave this line
// out, Meteor will never consider the subscription ready because
// it thinks you're using the added/changed/removed interface where
// you have to explicitly call this.ready().
return [];
}
});
Meteor will emit a warning message if you call Meteor.publish
in a
project that includes the autopublish
package. Your publish function
will still work.
Read more about publications and how to use them in the Data Loading article in the Meteor Guide.
Server
this.userId
Access inside the publish function. The id of the logged-in user, or null
if no user is logged in.
This is constant. However, if the logged-in user changes, the publish function is rerun with the new value.
Server
this.added(collection, id, fields)
Call inside the publish function. Informs the subscriber that a document has been added to the record set.
Arguments
- collection String
-
The name of the collection that contains the new document.
- id String
-
The new document's ID.
- fields Object
-
The fields in the new document. If
_id
is present it is ignored.
Server
this.changed(collection, id, fields)
Call inside the publish function. Informs the subscriber that a document in the record set has been modified.
Arguments
- collection String
-
The name of the collection that contains the changed document.
- id String
-
The changed document's ID.
- fields Object
-
The fields in the document that have changed, together with their new values. If a field is not present in
fields
it was left unchanged; if it is present infields
and has a value ofundefined
it was removed from the document. If_id
is present it is ignored.
Server
this.removed(collection, id)
Call inside the publish function. Informs the subscriber that a document has been removed from the record set.
Arguments
- collection String
-
The name of the collection that the document has been removed from.
- id String
-
The ID of the document that has been removed.
Server
this.ready()
Call inside the publish function. Informs the subscriber that an initial, complete snapshot of the record set has been sent. This will trigger a call on the client to the onReady
callback passed to Meteor.subscribe
, if any.
Server
this.onStop(func)
Call inside the publish function. Registers a callback function to run when the subscription is stopped.
Arguments
- func Function
-
The callback function
If you call observe
or observeChanges
in your
publish handler, this is the place to stop the observes.
Server
this.error(error)
Call inside the publish function. Stops this client's subscription, triggering a call on the client to the onStop
callback passed to Meteor.subscribe
, if any. If error
is not a Meteor.Error
, it will be sanitized.
Arguments
- error Error
-
The error to pass to the client.
Server
this.stop()
Call inside the publish function. Stops this client's subscription and invokes the client's onStop
callback with no error.
Server
this.connection
Access inside the publish function. The incoming connection for this subscription.
Client
Meteor.subscribe(name, [arg1, arg2...], [callbacks])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Subscribe to a record set. Returns a handle that provides
stop()
and ready()
methods.
Arguments
- name String
-
Name of the subscription. Matches the name of the server's
publish()
call. - arg1, arg2... EJSON-able Object
-
Optional arguments passed to publisher function on server.
- callbacks Function or Object
-
Optional. May include
onStop
andonReady
callbacks. If there is an error, it is passed as an argument toonStop
. If a function is passed instead of an object, it is interpreted as anonReady
callback.
When you subscribe to a record set, it tells the server to send records to the
client. The client stores these records in local Minimongo
collections, with the same name as the collection
argument used in the publish handler's added
,
changed
, and removed
callbacks. Meteor will queue incoming records until you declare the
Mongo.Collection
on the client with the matching
collection name.
// okay to subscribe (and possibly receive data) before declaring
// the client collection that will hold it. assume "allplayers"
// publishes data from server's "players" collection.
Meteor.subscribe("allplayers");
...
// client queues incoming players records until ...
...
Players = new Mongo.Collection("players");
The client will see a document if the document is currently in the published record set of any of its subscriptions.
The onReady
callback is called with no arguments when the server marks the
subscription as ready. The onStop
callback is called with
a Meteor.Error
if the subscription fails or is terminated by
the server. If the subscription is stopped by calling stop
on the subscription
handle or inside the publication, onStop
is called with no arguments.
Meteor.subscribe
returns a subscription handle, which is an object with the
following properties:
- stop()
Cancel the subscription. This will typically result in the server directing the client to remove the subscription's data from the client's cache.
- ready()
True if the server has marked the subscription as ready. A reactive data source.
- subscriptionId
The
id
of the subscription this handle is for. When you runMeteor.subscribe
inside ofTracker.autorun
, the handles you get will always have the samesubscriptionId
field. You can use this to deduplicate subscription handles if you are storing them in some data structure.
If you call Meteor.subscribe
within a reactive computation,
for example using
Tracker.autorun
, the subscription will automatically be
cancelled when the computation is invalidated or stopped; it's not necessary
to call stop
on
subscriptions made from inside autorun
. However, if the next iteration
of your run function subscribes to the same record set (same name and
parameters), Meteor is smart enough to skip a wasteful
unsubscribe/resubscribe. For example:
Tracker.autorun(function () {
Meteor.subscribe("chat", {room: Session.get("current-room")});
Meteor.subscribe("privateMessages");
});
This subscribes you to the chat messages in the current room and to your private
messages. When you change rooms by calling Session.set("current-room",
"new-room")
, Meteor will subscribe to the new room's chat messages,
unsubscribe from the original room's chat messages, and continue to
stay subscribed to your private messages.
If more than one subscription sends conflicting values for a field (same collection name, document ID, and field name), then the value on the client will be one of the published values, chosen arbitrarily.
Methods
Methods are remote functions that Meteor clients can invoke.
Anywhere
Meteor.methods(methods)
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Defines functions that can be invoked over the network by clients.
Arguments
- methods Object
-
Dictionary whose keys are method names and values are functions.
Example:
Meteor.methods({
foo: function (arg1, arg2) {
check(arg1, String);
check(arg2, [Number]);
// .. do stuff ..
if (/* you want to throw an error */) {
throw new Meteor.Error("pants-not-found", "Can't find my pants");
}
return "some return value";
},
bar: function () {
// .. do other stuff ..
return "baz";
}
});
Calling methods
on the server defines functions that can be called remotely by
clients. They should return an EJSON-able value or throw an
exception. Inside your method invocation, this
is bound to a method
invocation object, which provides the following:
isSimulation
: a boolean value, true if this invocation is a stub.unblock
: when called, allows the next method from this client to begin running.userId
: the id of the current user.setUserId
: a function that associates the current client with a user.connection
: on the server, the connection this method call was received on.
Calling methods
on the client defines stub functions associated with
server methods of the same name. You don't have to define a stub for
your method if you don't want to. In that case, method calls are just
like remote procedure calls in other systems, and you'll have to wait
for the results from the server.
If you do define a stub, when a client invokes a server method it will also run its stub in parallel. On the client, the return value of a stub is ignored. Stubs are run for their side-effects: they are intended to simulate the result of what the server's method will do, but without waiting for the round trip delay. If a stub throws an exception it will be logged to the console.
You use methods all the time, because the database mutators
(insert
, update
, remove
) are implemented
as methods. When you call any of these functions on the client, you're invoking
their stub version that update the local cache, and sending the same write
request to the server. When the server responds, the client updates the local
cache with the writes that actually occurred on the server.
You don't have to put all your method definitions into a single Meteor.methods
call; you may call it multiple times, as long as each method has a unique name.
If a client calls a method and is disconnected before it receives a response,
it will re-call the method when it reconnects. This means that a client may
call a method multiple times when it only means to call it once. If this
behavior is problematic for your method, consider attaching a unique ID
to each method call on the client, and checking on the server whether a call
with this ID has already been made. Alternatively, you can use
Meteor.apply
with the noRetry option set to true.
Read more about methods and how to use them in the Methods article in the Meteor Guide.
Anywhere
this.userId
The id of the user that made this method call, or null
if no user was logged in.
The user id is an arbitrary string — typically the id of the user record
in the database. You can set it with the setUserId
function. If you're using
the Meteor accounts system then this is handled for you.
Server
this.setUserId(userId)
Set the logged in user.
Arguments
- userId String or null
-
The value that should be returned by
userId
on this connection.
Call this function to change the currently logged in user on the
connection that made this method call. This simply sets the value of
userId
for future method calls received on this connection. Pass
null
to log out the connection.
If you are using the built-in Meteor accounts system then this
should correspond to the _id
field of a document in the
Meteor.users
collection.
setUserId
is not retroactive. It affects the current method call and
any future method calls on the connection. Any previous method calls on
this connection will still see the value of userId
that was in effect
when they started.
Anywhere
this.isSimulation
Access inside a method invocation. Boolean value, true if this invocation is a stub.
Server
this.unblock()
Call inside a method invocation. Allow subsequent method from this client to begin running in a new fiber.
On the server, methods from a given client run one at a time. The N+1th
invocation from a client won't start until the Nth invocation
returns. However, you can change this by calling this.unblock
. This
will allow the N+1th invocation to start running in a new fiber.
Server
this.connection
Access inside a method invocation. The connection that this method was received on. null
if the method is not associated with a connection, eg. a server initiated method call.
Anywhere
new Meteor.Error(error, [reason], [details])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
This class represents a symbolic error thrown by a method.
Arguments
- error String
-
A string code uniquely identifying this kind of error. This string should be used by callers of the method to determine the appropriate action to take, instead of attempting to parse the reason or details fields. For example:
// on the server, pick a code unique to this error // the reason field should be a useful debug message throw new Meteor.Error("logged-out", "The user must be logged in to post a comment."); // on the client Meteor.call("methodName", function (error) { // identify the error if (error && error.error === "logged-out") { // show a nice error message Session.set("errorMessage", "Please log in to post a comment."); } });
For legacy reasons, some built-in Meteor functions such as
check
throw errors with a number in this field. - reason String
-
Optional. A short human-readable summary of the error, like 'Not Found'.
- details String
-
Optional. Additional information about the error, like a textual stack trace.
If you want to return an error from a method, throw an exception. Methods can
throw any kind of exception. But Meteor.Error
is the only kind of error that
a server will send to the client. If a method function throws a different
exception, then it will be mapped to a sanitized version on the
wire. Specifically, if the sanitizedError
field on the thrown error is set to
a Meteor.Error
, then that error will be sent to the client. Otherwise, if no
sanitized version is available, the client gets
Meteor.Error(500, 'Internal server error')
.
Anywhere
Meteor.call(name, [arg1, arg2...], [asyncCallback])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Invokes a method passing any number of arguments.
Arguments
- name String
-
Name of method to invoke
- arg1, arg2... EJSON-able Object
-
Optional method arguments
- asyncCallback Function
-
Optional callback, which is called asynchronously with the error or result after the method is complete. If not provided, the method runs synchronously if possible (see below).
This is how to invoke a method. It will run the method on the server. If a
stub is available, it will also run the stub on the client. (See also
Meteor.apply
, which is identical to Meteor.call
except that
you specify the parameters as an array instead of as separate arguments and you
can specify a few options controlling how the method is executed.)
If you include a callback function as the last argument (which can't be
an argument to the method, since functions aren't serializable), the
method will run asynchronously: it will return nothing in particular and
will not throw an exception. When the method is complete (which may or
may not happen before Meteor.call
returns), the callback will be
called with two arguments: error
and result
. If an error was thrown,
then error
will be the exception object. Otherwise, error
will be
undefined and the return value (possibly undefined) will be in result
.
// async call
Meteor.call('foo', 1, 2, function (error, result) { ... } );
If you do not pass a callback on the server, the method invocation will
block until the method is complete. It will eventually return the
return value of the method, or it will throw an exception if the method
threw an exception. (Possibly mapped to 500 Server Error if the
exception happened remotely and it was not a Meteor.Error
exception.)
// sync call
var result = Meteor.call('foo', 1, 2);
On the client, if you do not pass a callback and you are not inside a
stub, call
will return undefined
, and you will have no way to get
the return value of the method. That is because the client doesn't have
fibers, so there is not actually any way it can block on the remote
execution of a method.
Finally, if you are inside a stub on the client and call another
method, the other method is not executed (no RPC is generated, nothing
"real" happens). If that other method has a stub, that stub stands in
for the method and is executed. The method call's return value is the
return value of the stub function. The client has no problem executing
a stub synchronously, and that is why it's okay for the client to use
the synchronous Meteor.call
form from inside a method body, as
described earlier.
Meteor tracks the database writes performed by methods, both on the client and
the server, and does not invoke asyncCallback
until all of the server's writes
replace the stub's writes in the local cache. In some cases, there can be a lag
between the method's return value being available and the writes being visible:
for example, if another method still outstanding wrote to the same document, the
local cache may not be up to date until the other method finishes as well. If
you want to process the method's result as soon as it arrives from the server,
even if the method's writes are not available yet, you can specify an
onResultReceived
callback to Meteor.apply
.
Anywhere
Meteor.apply(name, args, [options], (Boolean), [asyncCallback])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Invoke a method passing an array of arguments.
Arguments
- name String
-
Name of method to invoke
- args Array of EJSON-able Objects
-
Method arguments
- (Boolean) , or undefined
-
options.noRetry (Client only) if true, don't send this method again on reload, simply call the callback an error with the error code 'invocation-failed'.
- asyncCallback Function
-
Optional callback; same semantics as in
Meteor.call
.
Options
- wait Boolean
-
(Client only) If true, don't send this method until all previous method calls have completed, and don't send any subsequent method calls until this one is completed.
- onResultReceived Function
-
(Client only) This callback is invoked with the error or result of the method (just like
asyncCallback
) as soon as the error or result is available. The local cache may not yet reflect the writes performed by the method.
Meteor.apply
is just like Meteor.call
, except that the method arguments are
passed as an array rather than directly as arguments, and you can specify
options about how the client executes the method.
DDPRateLimiter
Customize rate limiting for methods and subscriptions.
By default, DDPRateLimiter
is configured with a single rule. This rule
limits login attempts, new user creation, and password resets to 5 attempts
every 10 seconds per connection. It can be removed by calling
Accounts.removeDefaultRateLimit()
.
Server
DDPRateLimiter.addRule(matcher, numRequests, timeInterval)
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter'
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter'
Add a rule that matches against a stream of events describing method or subscription attempts. Each event is an object with the following properties:
type
: Either "method" or "subscription"name
: The name of the method or subscription being calleduserId
: The user ID attempting the method or subscriptionconnectionId
: A string representing the user's DDP connectionclientAddress
: The IP address of the user
Returns unique ruleId
that can be passed to removeRule
.
Arguments
- matcher Object
-
Matchers specify which events are counted towards a rate limit. A matcher is an object that has a subset of the same properties as the event objects described above. Each value in a matcher object is one of the following:
a string: for the event to satisfy the matcher, this value must be equal to the value of the same property in the event object
a function: for the event to satisfy the matcher, the function must evaluate to true when passed the value of the same property in the event object
Here's how events are counted: Each event that satisfies the matcher's filter is mapped to a bucket. Buckets are uniquely determined by the event object's values for all properties present in both the matcher and event objects.
- numRequests number
-
number of requests allowed per time interval. Default = 10.
- timeInterval number
-
time interval in milliseconds after which rule's counters are reset. Default = 1000.
Custom rules can be added by calling DDPRateLimiter.addRule
. The rate
limiter is called on every method and subscription invocation.
A rate limit is reached when a bucket has surpassed the rule's predefined capactiy, at which point errors will be returned for that input until the buckets are reset. Buckets are regularly reset after the end of a time interval.
Here's example of defining a rule and adding it into the DDPRateLimiter
:
// Define a rule that matches login attempts by non-admin users
var loginRule = {
userId: function (userId) {
return Meteor.users.findOne(userId).type !== 'Admin';
},
type: 'method',
name: 'login'
}
// Add the rule, allowing up to 5 messages every 1000 milliseconds.
DDPRateLimiter.addRule(loginRule, 5, 1000);
Server
DDPRateLimiter.removeRule(id)
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter'
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter'
Removes the specified rule from the rate limiter. If rule had hit a rate limit, that limit is removed as well.
Arguments
- id string
-
'ruleId' returned from
addRule
Server
DDPRateLimiter.setErrorMessage(message)
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter'
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter'
Set error message text when method or subscription rate limit exceeded.
Arguments
- message string or Function
-
Functions are passed in an object with a
timeToReset
field that specifies the number of milliseconds until the next method or subscription is allowed to run. The function must return a string of the error message.
Check
The check
package includes pattern checking functions useful for checking the types and structure
of variables and an extensible library of patterns to specify which types you are
expecting.
Anywhere
check(value, pattern)
import { check } from 'meteor/check'
import { check } from 'meteor/check'
Check that a value matches a pattern.
If the value does not match the pattern, throw a Match.Error
.
Particularly useful to assert that arguments to a function have the right types and structure.
Arguments
- value Any
-
The value to check
- pattern Match Pattern
-
The pattern to match
value
against
Meteor methods and publish functions can take arbitrary EJSON types as arguments, but most
functions expect their arguments to be of a particular type. check
is a lightweight function for
checking that arguments and other values are of the expected type. For example:
Meteor.publish("chats-in-room", function (roomId) {
// Make sure roomId is a string, not an arbitrary mongo selector object.
check(roomId, String);
return Chats.find({room: roomId});
});
Meteor.methods({addChat: function (roomId, message) {
check(roomId, String);
check(message, {
text: String,
timestamp: Date,
// Optional, but if present must be an array of strings.
tags: Match.Maybe([String])
});
// ... do something with the message ...
}});
If the match fails, check
throws a Match.Error
describing how it failed. If
this error gets sent over the wire to the client, it will appear only as
Meteor.Error(400, "Match Failed")
. The failure details will be written to the
server logs but not revealed to the client.
Anywhere
Match.test(value, pattern)
import { Match } from 'meteor/check'
import { Match } from 'meteor/check'
Returns true if the value matches the pattern.
Arguments
- value Any
-
The value to check
- pattern Match Pattern
-
The pattern to match
value
against
Match.test
can be used to identify if a variable has a certain structure.
// will return true for {foo: 1, bar: "hello"} or similar
Match.test(value, {foo: Match.Integer, bar: String});
// will return true if value is a string
Match.test(value, String);
// will return true if value is a String or an array of Numbers
Match.test(value, Match.OneOf(String, [Number]));
This can be useful if you have a function that accepts several different kinds of objects, and you want to determine which was passed in.
Match Patterns
The following patterns can be used as pattern arguments to
check
and Match.test
:
Match.Any
Matches any value.
String
,Number
,Boolean
,undefined
,null
Matches a primitive of the given type.
Match.Integer
Matches a signed 32-bit integer. Doesn't match
Infinity
,-Infinity
, orNaN
.[pattern]
A one-element array matches an array of elements, each of which match pattern. For example,
[Number]
matches a (possibly empty) array of numbers;[Match.Any]
matches any array.{key1: pattern1, key2: pattern2, ...}
Matches an Object with the given keys, with values matching the given patterns. If any pattern is a
Match.Maybe
orMatch.Optional
, that key does not need to exist in the object. The value may not contain any keys not listed in the pattern. The value must be a plain Object with no special prototype.Match.ObjectIncluding({key1: pattern1, key2: pattern2, ...})
Matches an Object with the given keys; the value may also have other keys with arbitrary values.
Object
Matches any plain Object with any keys; equivalent to
Match.ObjectIncluding({})
.Match.Maybe(pattern)
Matches either
undefined
,null
, or pattern. If used in an object, matches only if the key is not set as opposed to the value being set toundefined
ornull
. This set of conditions was chosen becauseundefined
arguments to Meteor Methods are converted tonull
when sent over the wire.// In an object var pattern = { name: Match.Maybe(String) }; check({ name: "something" }, pattern) // OK check({}, pattern) // OK check({ name: undefined }, pattern) // Throws an exception check({ name: null }, pattern) // Throws an exception // Outside an object check(null, Match.Maybe(String)); // OK check(undefined, Match.Maybe(String)); // OK
Match.Optional(pattern)
Behaves like
Match.Maybe
except it doesn't acceptnull
. If used in an object, the behavior is identical toMatch.Maybe
.Match.OneOf(pattern1, pattern2, ...)
Matches any value that matches at least one of the provided patterns.
- Any constructor function (eg,
Date
) Matches any element that is an instance of that type.
Match.Where(condition)
Calls the function condition with the value as the argument. If condition returns true, this matches. If condition throws a
Match.Error
or returns false, this fails. If condition throws any other error, that error is thrown from the call tocheck
orMatch.test
. Examples:check(buffer, Match.Where(EJSON.isBinary)); NonEmptyString = Match.Where(function (x) { check(x, String); return x.length > 0; }); check(arg, NonEmptyString);
Server connections
These functions manage and inspect the network connection between the Meteor client and server.
Client
Meteor.status()
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Get the current connection status. A reactive data source.
This method returns the status of the connection between the client and the server. The return value is an object with the following fields:
- connected Boolean
True if currently connected to the server. If false, changes and method invocations will be queued up until the connection is reestablished.
- status String
Describes the current reconnection status. The possible values are
connected
(the connection is up and running),connecting
(disconnected and trying to open a new connection),failed
(permanently failed to connect; e.g., the client and server support different versions of DDP),waiting
(failed to connect and waiting to try to reconnect) andoffline
(user has disconnected the connection).- retryCount Number
The number of times the client has tried to reconnect since the connection was lost. 0 when connected.
- retryTime Number or undefined
The estimated time of the next reconnection attempt. To turn this into an interval until the next reconnection, use
retryTime - (new Date()).getTime()
. This key will be set only whenstatus
iswaiting
.- reason String or undefined
If
status
isfailed
, a description of why the connection failed.
Instead of using callbacks to notify you on changes, this is a reactive data source. You can use it in a template or computation to get realtime updates.
Client
Meteor.reconnect()
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Force an immediate reconnection attempt if the client is not connected to the server.
This method does nothing if the client is already connected.
Client
Meteor.disconnect()
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Disconnect the client from the server.
Call this method to disconnect from the server and stop all live data updates. While the client is disconnected it will not receive updates to collections, method calls will be queued until the connection is reestablished, and hot code push will be disabled.
Call Meteor.reconnect to reestablish the connection and resume data transfer.
This can be used to save battery on mobile devices when real time updates are not required.
Server
Meteor.onConnection(callback)
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Register a callback to be called when a new DDP connection is made to the server.
Arguments
- callback Function
-
The function to call when a new DDP connection is established.
onConnection
returns an object with a single method stop
. Calling
stop
unregisters the callback, so that this callback will no longer
be called on new connections.
The callback is called with a single argument, the server-side
connection
representing the connection from the client. This object
contains the following fields:
- id String
A globally unique id for this connection.
- close Function
Close this DDP connection. The client is free to reconnect, but will receive a different connection with a new
id
if it does.- onClose Function
Register a callback to be called when the connection is closed. If the connection is already closed, the callback will be called immediately.
- clientAddress String
The IP address of the client in dotted form (such as
"<IP_ADDRESS>"
).If you're running your Meteor server behind a proxy (so that clients are connecting to the proxy instead of to your server directly), you'll need to set the
HTTP_FORWARDED_COUNT
environment variable for the correct IP address to be reported byclientAddress
.Set
HTTP_FORWARDED_COUNT
to an integer representing the number of proxies in front of your server. For example, you'd set it to"1"
when your server was behind one proxy.- httpHeaders Object
When the connection came in over an HTTP transport (such as with Meteor's default SockJS implementation), this field contains whitelisted HTTP headers.
Cookies are deliberately excluded from the headers as they are a security risk for this transport. For details and alternatives, see the SockJS documentation.
Currently when a client reconnects to the server (such as after
temporarily losing its Internet connection), it will get a new
connection each time. The onConnection
callbacks will be called
again, and the new connection will have a new connection id
.
In the future, when client reconnection is fully implemented,
reconnecting from the client will reconnect to the same connection on
the server: the onConnection
callback won't be called for that
connection again, and the connection will still have the same
connection id
.
Anywhere
DDP.connect(url)
import { DDP } from 'meteor/ddp-client'
import { DDP } from 'meteor/ddp-client'
Connect to the server of a different Meteor application to subscribe to its document sets and invoke its remote methods.
Arguments
- url String
-
The URL of another Meteor application.
To call methods on another Meteor application or subscribe to its data
sets, call DDP.connect
with the URL of the application.
DDP.connect
returns an object which provides:
subscribe
- Subscribe to a record set. See Meteor.subscribe.call
- Invoke a method. See Meteor.call.apply
- Invoke a method with an argument array. See Meteor.apply.methods
- Define client-only stubs for methods defined on the remote server. See Meteor.methods.status
- Get the current connection status. See Meteor.status.reconnect
- See Meteor.reconnect.disconnect
- See Meteor.disconnect.onReconnect
- Set this to a function to be called as the first step of reconnecting. This function can call methods which will be executed before any other outstanding methods. For example, this can be used to re-establish the appropriate authentication context on the new connection.
By default, clients open a connection to the server from which they're loaded.
When you call Meteor.subscribe
, Meteor.status
, Meteor.call
, and
Meteor.apply
, you are using a connection back to that default
server.
Collections
Meteor stores data in collections. To get started, declare a
collection with new Mongo.Collection
.
Anywhere
new Mongo.Collection(name, [options])
import { Mongo } from 'meteor/mongo'
import { Mongo } from 'meteor/mongo'
Constructor for a Collection
Arguments
- name String
-
The name of the collection. If null, creates an unmanaged (unsynchronized) local collection.
Options
- connection Object
-
The server connection that will manage this collection. Uses the default connection if not specified. Pass the return value of calling
DDP.connect
to specify a different server. Passnull
to specify no connection. Unmanaged (name
is null) collections cannot specify a connection. - idGeneration String
-
The method of generating the
_id
fields of new documents in this collection. Possible values:'STRING'
: random strings'MONGO'
: randomMongo.ObjectID
values
The default id generation technique is
'STRING'
. - transform Function
-
An optional transformation function. Documents will be passed through this function before being returned from
fetch
orfindOne
, and before being passed to callbacks ofobserve
,map
,forEach
,allow
, anddeny
. Transforms are not applied for the callbacks ofobserveChanges
or to cursors returned from publish functions.
Calling this function is analogous to declaring a model in a traditional ORM
(Object-Relation Mapper)-centric framework. It sets up a collection (a storage
space for records, or "documents") that can be used to store a particular type
of information, like users, posts, scores, todo items, or whatever matters to
your application. Each document is a EJSON object. It includes an _id
property whose value is unique in the collection, which Meteor will set when you
first create the document.
// common code on client and server declares a DDP-managed mongo
// collection.
Chatrooms = new Mongo.Collection("chatrooms");
Messages = new Mongo.Collection("messages");
The function returns an object with methods to insert
documents in the collection, update
their properties, and
remove
them, and to find
the documents in the
collection that match arbitrary criteria. The way these methods work is
compatible with the popular Mongo database API. The same database API
works on both the client and the server (see below).
// return array of my messages
var myMessages = Messages.find({userId: Session.get('myUserId')}).fetch();
// create a new message
Messages.insert({text: "Hello, world!"});
// mark my first message as "important"
Messages.update(myMessages[0]._id, {$set: {important: true}});
If you pass a name
when you create the collection, then you are
declaring a persistent collection — one that is stored on the
server and seen by all users. Client code and server code can both
access the same collection using the same API.
Specifically, when you pass a name
, here's what happens:
On the server (if you do not specify a
connection
), a collection with that name is created on a backend Mongo server. When you call methods on that collection on the server, they translate directly into normal Mongo operations (after checking that they match your access control rules).On the client (and on the server if you specify a
connection
), a Minimongo instance is created. Minimongo is essentially an in-memory, non-persistent implementation of Mongo in pure JavaScript. It serves as a local cache that stores just the subset of the database that this client is working with. Queries (find
) on these collections are served directly out of this cache, without talking to the server.When you write to the database on the client (
insert
,update
,remove
), the command is executed locally immediately, and, simultaneously, it's sent to the server and executed there too. This happens via stubs, because writes are implemented as methods.
When, on the server, you write to a collection which has a specified
connection
to another server, it sends the corresponding method to the other
server and receives the changed values back from it over DDP. Unlike on the
client, it does not execute the write locally first.
If you pass null
as the name
, then you're creating a local
collection. It's not synchronized anywhere; it's just a local scratchpad
that supports Mongo-style find
, insert
,
update
, and remove
operations. (On both the
client and the server, this scratchpad is implemented using Minimongo.)
By default, Meteor automatically publishes every document in your
collection to each connected client. To turn this behavior off, remove
the autopublish
package, in your terminal:
meteor remove autopublish
and instead call Meteor.publish
to specify which parts of
your collection should be published to which users.
// Create a collection called Posts and put a document in it. The
// document will be immediately visible in the local copy of the
// collection. It will be written to the server-side database
// a fraction of a second later, and a fraction of a second
// after that, it will be synchronized down to any other clients
// that are subscribed to a query that includes it (see
// Meteor.subscribe and autopublish)
Posts = new Mongo.Collection("posts");
Posts.insert({title: "Hello world", body: "First post"});
// Changes are visible immediately -- no waiting for a round trip to
// the server.
assert(Posts.find().count() === 1);
// Create a temporary, local collection. It works just like any other
// collection, but it doesn't send changes to the server, and it
// can't receive any data from subscriptions.
Scratchpad = new Mongo.Collection;
for (var i = 0; i < 10; i++)
Scratchpad.insert({number: i * 2});
assert(Scratchpad.find({number: {$lt: 9}}).count() === 5);
Generally, you'll assign Mongo.Collection
objects in your app to global
variables. You can only create one Mongo.Collection
object for each
underlying Mongo collection.
If you specify a transform
option to the Collection
or any of its retrieval
methods, documents are passed through the transform
function before being
returned or passed to callbacks. This allows you to add methods or otherwise
modify the contents of your collection from their database representation. You
can also specify transform
on a particular find
, findOne
, allow
, or
deny
call. Transform functions must return an object and they may not change
the value of the document's _id
field (though it's OK to leave it out).
// An Animal class that takes a document in its constructor
Animal = function (doc) {
_.extend(this, doc);
};
_.extend(Animal.prototype, {
makeNoise: function () {
console.log(this.sound);
}
});
// Define a Collection that uses Animal as its document
Animals = new Mongo.Collection("Animals", {
transform: function (doc) { return new Animal(doc); }
});
// Create an Animal and call its makeNoise method
Animals.insert({name: "raptor", sound: "roar"});
Animals.findOne({name: "raptor"}).makeNoise(); // prints "roar"
transform
functions are not called reactively. If you want to add a
dynamically changing attribute to an object, do it with a function that computes
the value at the time it's called, not by computing the attribute at transform
time.
In this release, Minimongo has some limitations:
$pull
in modifiers can only accept certain kinds of selectors.findAndModify
, aggregate functions, and map/reduce aren't supported.
All of these will be addressed in a future release. For full Minimongo release notes, see packages/minimongo/NOTES in the repository.
Minimongo doesn't currently have indexes. It's rare for this to be an issue, since it's unusual for a client to have enough data that an index is worthwhile.
Read more about collections and how to use them in the Collections article in the Meteor Guide.
Anywhere
collection.find([selector], [options])
Find the documents in a collection that match the selector.
Arguments
- selector Mongo Selector, Object ID, or String
-
A query describing the documents to find
Options
- sort Mongo Sort Specifier
-
Sort order (default: natural order)
- skip Number
-
Number of results to skip at the beginning
- limit Number
-
Maximum number of results to return
- fields Mongo Field Specifier
-
Dictionary of fields to return or exclude.
- reactive Boolean
-
(Client only) Default
true
; passfalse
to disable reactivity - transform Function
-
Overrides
transform
on theCollection
for this cursor. Passnull
to disable transformation. - disableOplog Boolean
-
(Server only) Pass true to disable oplog-tailing on this query. This affects the way server processes calls to
observe
on this query. Disabling the oplog can be useful when working with data that updates in large batches. - pollingIntervalMs Number
-
(Server only) How often to poll this query when observing on the server. In milliseconds. Defaults to 10 seconds.
- pollingThrottleMs Number
-
(Server only) Minimum time to allow between re-polling. Increasing this will save CPU and mongo load at the expense of slower updates to users. Decreasing this is not recommended. In milliseconds. Defaults to 50 milliseconds.
find
returns a cursor. It does not immediately access the database or return
documents. Cursors provide fetch
to return all matching documents, map
and
forEach
to iterate over all matching documents, and observe
and
observeChanges
to register callbacks when the set of matching documents
changes.
Collection cursors are not query snapshots. If the database changes
between calling Collection.find
and fetching the
results of the cursor, or while fetching results from the cursor,
those changes may or may not appear in the result set.
Cursors are a reactive data source. On the client, the first time you retrieve a
cursor's documents with fetch
, map
, or forEach
inside a
reactive computation (eg, a template or
autorun
), Meteor will register a
dependency on the underlying data. Any change to the collection that
changes the documents in a cursor will trigger a recomputation. To
disable this behavior, pass {reactive: false}
as an option to
find
.
Note that when fields
are specified, only changes to the included
fields will trigger callbacks in observe
, observeChanges
and
invalidations in reactive computations using this cursor. Careful use
of fields
allows for more fine-grained reactivity for computations
that don't depend on an entire document.
Anywhere
collection.findOne([selector], [options])
Finds the first document that matches the selector, as ordered by sort and skip options.
Arguments
- selector Mongo Selector, Object ID, or String
-
A query describing the documents to find
Options
- sort Mongo Sort Specifier
-
Sort order (default: natural order)
- skip Number
-
Number of results to skip at the beginning
- fields Mongo Field Specifier
-
Dictionary of fields to return or exclude.
- reactive Boolean
-
(Client only) Default true; pass false to disable reactivity
- transform Function
-
Overrides
transform
on theCollection
for this cursor. Passnull
to disable transformation.
Equivalent to find(selector, options).fetch()[0]
with
options.limit = 1
.
Anywhere
collection.insert(doc, [callback])
Insert a document in the collection. Returns its unique _id.
Arguments
- doc Object
-
The document to insert. May not yet have an _id attribute, in which case Meteor will generate one for you.
- callback Function
-
Optional. If present, called with an error object as the first argument and, if no error, the _id as the second.
Add a document to the collection. A document is just an object, and
its fields can contain any combination of EJSON-compatible datatypes
(arrays, objects, numbers, strings, null
, true, and false).
insert
will generate a unique ID for the object you pass, insert it
in the database, and return the ID. When insert
is called from
untrusted client code, it will be allowed only if passes any
applicable allow
and deny
rules.
On the server, if you don't provide a callback, then insert
blocks
until the database acknowledges the write, or throws an exception if
something went wrong. If you do provide a callback, insert
still
returns the ID immediately. Once the insert completes (or fails), the
callback is called with error and result arguments. In an error case,
result
is undefined. If the insert is successful, error
is
undefined and result
is the new document ID.
On the client, insert
never blocks. If you do not provide a callback
and the insert fails on the server, then Meteor will log a warning to
the console. If you provide a callback, Meteor will call that function
with error
and result
arguments. In an error case, result
is
undefined. If the insert is successful, error
is undefined and
result
is the new document ID.
Example:
var groceriesId = Lists.insert({name: "Groceries"});
Items.insert({list: groceriesId, name: "Watercress"});
Items.insert({list: groceriesId, name: "Persimmons"});
Anywhere
collection.update(selector, modifier, [options], [callback])
Modify one or more documents in the collection. Returns the number of affected documents.
Arguments
- selector Mongo Selector, Object ID, or String
-
Specifies which documents to modify
- modifier Mongo Modifier
-
Specifies how to modify the documents
- callback Function
-
Optional. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second.
Options
- multi Boolean
-
True to modify all matching documents; false to only modify one of the matching documents (the default).
- upsert Boolean
-
True to insert a document if no matching documents are found.
Modify documents that match selector
according to modifier
(see
modifier documentation).
The behavior of update
differs depending on whether it is called by
trusted or untrusted code. Trusted code includes server code and
method code. Untrusted code includes client-side code such as event
handlers and a browser's JavaScript console.
Trusted code can modify multiple documents at once by setting
multi
to true, and can use an arbitrary Mongo selector to find the documents to modify. It bypasses any access control rules set up byallow
anddeny
. The number of affected documents will be returned from theupdate
call if you don't pass a callback.Untrusted code can only modify a single document at once, specified by its
_id
. The modification is allowed only after checking any applicableallow
anddeny
rules. The number of affected documents will be returned to the callback. Untrusted code cannot perform upserts, except in insecure mode.
On the server, if you don't provide a callback, then update
blocks
until the database acknowledges the write, or throws an exception if
something went wrong. If you do provide a callback, update
returns
immediately. Once the update completes, the callback is called with a
single error argument in the case of failure, or a second argument
indicating the number of affected documents if the update was successful.
On the client, update
never blocks. If you do not provide a callback
and the update fails on the server, then Meteor will log a warning to
the console. If you provide a callback, Meteor will call that function
with an error argument if there was an error, or a second argument
indicating the number of affected documents if the update was successful.
Client example:
// When the givePoints button in the admin dashboard is pressed,
// give 5 points to the current player. The new score will be
// immediately visible on everyone's screens.
Template.adminDashboard.events({
'click .givePoints': function () {
Players.update(Session.get("currentPlayer"), {$inc: {score: 5}});
}
});
Server example:
// Give the "Winner" badge to each user with a score greater than
// 10. If they are logged in and their badge list is visible on the
// screen, it will update automatically as they watch.
Meteor.methods({
declareWinners: function () {
Players.update({score: {$gt: 10}},
{$addToSet: {badges: "Winner"}},
{multi: true});
}
});
You can use update
to perform a Mongo upsert by setting the upsert
option to true. You can also use the upsert
method to perform an
upsert that returns the _id of the document that was inserted (if there was one)
in addition to the number of affected documents.
Anywhere
collection.upsert(selector, modifier, [options], [callback])
Modify one or more documents in the collection, or insert one if no matching documents were found. Returns an object with keys numberAffected
(the number of documents modified) and insertedId
(the unique _id of the document that was inserted, if any).
Arguments
- selector Mongo Selector, Object ID, or String
-
Specifies which documents to modify
- modifier Mongo Modifier
-
Specifies how to modify the documents
- callback Function
-
Optional. If present, called with an error object as the first argument and, if no error, the number of affected documents as the second.
Options
- multi Boolean
-
True to modify all matching documents; false to only modify one of the matching documents (the default).
Modify documents that match selector
according to modifier
, or insert
a document if no documents were modified. upsert
is the same as calling
update
with the upsert
option set to true, except that the return
value of upsert
is an object that contain the keys numberAffected
and insertedId
. (update
returns only the number of affected documents.)
Anywhere
collection.remove(selector, [callback])
Remove documents from the collection
Arguments
- selector Mongo Selector, Object ID, or String
-
Specifies which documents to remove
- callback Function
-
Optional. If present, called with an error object as its argument.
Find all of the documents that match selector
and delete them from
the collection.
The behavior of remove
differs depending on whether it is called by
trusted or untrusted code. Trusted code includes server code and
method code. Untrusted code includes client-side code such as event
handlers and a browser's JavaScript console.
Trusted code can use an arbitrary Mongo selector to find the documents to remove, and can remove more than one document at once by passing a selector that matches multiple documents. It bypasses any access control rules set up by
allow
anddeny
. The number of removed documents will be returned fromremove
if you don't pass a callback.As a safety measure, if
selector
is omitted (or isundefined
), no documents will be removed. Setselector
to{}
if you really want to remove all documents from your collection.Untrusted code can only remove a single document at a time, specified by its
_id
. The document is removed only after checking any applicableallow
anddeny
rules. The number of removed documents will be returned to the callback.
On the server, if you don't provide a callback, then remove
blocks
until the database acknowledges the write and then returns the number
of removed documents, or throws an exception if
something went wrong. If you do provide a callback, remove
returns
immediately. Once the remove completes, the callback is called with a
single error argument in the case of failure, or a second argument
indicating the number of removed documents if the remove was successful.
On the client, remove
never blocks. If you do not provide a callback
and the remove fails on the server, then Meteor will log a warning to the
console. If you provide a callback, Meteor will call that function with an
error argument if there was an error, or a second argument indicating the number
of removed documents if the remove was successful.
Client example:
// When the remove button is clicked on a chat message, delete
// that message.
Template.chat.events({
'click .remove': function () {
Messages.remove(this._id);
}
});
Server example:
// When the server starts, clear the log, and delete all players
// with a karma of less than -2.
Meteor.startup(function () {
if (Meteor.isServer) {
Logs.remove({});
Players.remove({karma: {$lt: -2}});
}
});
Server
collection.allow(options)
Allow users to write directly to this collection from client code, subject to limitations you define.
Options
- insert, update, remove Function
-
Functions that look at a proposed modification to the database and return true if it should be allowed.
- fetch Array of Strings
-
Optional performance enhancement. Limits the fields that will be fetched from the database for inspection by your
update
andremove
functions. - transform Function
-
Overrides
transform
on theCollection
. Passnull
to disable transformation.
When a client calls insert
, update
, or remove
on a collection, the
collection's allow
and deny
callbacks are called
on the server to determine if the write should be allowed. If at least
one allow
callback allows the write, and no deny
callbacks deny the
write, then the write is allowed to proceed.
These checks are run only when a client tries to write to the database
directly, for example by calling update
from inside an event
handler. Server code is trusted and isn't subject to allow
and deny
restrictions. That includes methods that are called with Meteor.call
— they are expected to do their own access checking rather than
relying on allow
and deny
.
You can call allow
as many times as you like, and each call can
include any combination of insert
, update
, and remove
functions. The functions should return true
if they think the
operation should be allowed. Otherwise they should return false
, or
nothing at all (undefined
). In that case Meteor will continue
searching through any other allow
rules on the collection.
The available callbacks are:
- insert(userId, doc)
The user
userId
wants to insert the documentdoc
into the collection. Returntrue
if this should be allowed.doc
will contain the_id
field if one was explicitly set by the client, or if there is an activetransform
. You can use this to prevent users from specifying arbitrary_id
fields.- update(userId, doc, fieldNames, modifier)
The user
userId
wants to update a documentdoc
. (doc
is the current version of the document from the database, without the proposed update.) Returntrue
to permit the change.fieldNames
is an array of the (top-level) fields indoc
that the client wants to modify, for example['name',
'score']
.modifier
is the raw Mongo modifier that the client wants to execute; for example,{$set: {'name.first': "Alice"}, $inc: {score: 1}}
.Only Mongo modifiers are supported (operations like
$set
and$push
). If the user tries to replace the entire document rather than use $-modifiers, the request will be denied without checking theallow
functions.- remove(userId, doc)
The user
userId
wants to removedoc
from the database. Returntrue
to permit this.
When calling update
or remove
Meteor will by default fetch the
entire document doc
from the database. If you have large documents
you may wish to fetch only the fields that are actually used by your
functions. Accomplish this by setting fetch
to an array of field
names to retrieve.
Example:
// Create a collection where users can only modify documents that
// they own. Ownership is tracked by an 'owner' field on each
// document. All documents must be owned by the user that created
// them and ownership can't be changed. Only a document's owner
// is allowed to delete it, and the 'locked' attribute can be
// set on a document to prevent its accidental deletion.
Posts = new Mongo.Collection("posts");
Posts.allow({
insert: function (userId, doc) {
// the user must be logged in, and the document must be owned by the user
return (userId && doc.owner === userId);
},
update: function (userId, doc, fields, modifier) {
// can only change your own documents
return doc.owner === userId;
},
remove: function (userId, doc) {
// can only remove your own documents
return doc.owner === userId;
},
fetch: ['owner']
});
Posts.deny({
update: function (userId, doc, fields, modifier) {
// can't change owners
return _.contains(fields, 'owner');
},
remove: function (userId, doc) {
// can't remove locked documents
return doc.locked;
},
fetch: ['locked'] // no need to fetch 'owner'
});
If you never set up any allow
rules on a collection then all client
writes to the collection will be denied, and it will only be possible to
write to the collection from server-side code. In this case you will
have to create a method for each possible write that clients are allowed
to do. You'll then call these methods with Meteor.call
rather than
having the clients call insert
, update
, and remove
directly on the
collection.
Meteor also has a special "insecure mode" for quickly prototyping new
applications. In insecure mode, if you haven't set up any allow
or deny
rules on a collection, then all users have full write access to the
collection. This is the only effect of insecure mode. If you call allow
or
deny
at all on a collection, even Posts.allow({})
, then access is checked
just like normal on that collection. New Meteor projects start in insecure
mode by default. To turn it off just run in your terminal:
meteor remove insecure
Server
collection.deny(options)
Override allow
rules.
Options
- insert, update, remove Function
-
Functions that look at a proposed modification to the database and return true if it should be denied, even if an allow rule says otherwise.
- fetch Array of Strings
-
Optional performance enhancement. Limits the fields that will be fetched from the database for inspection by your
update
andremove
functions. - transform Function
-
Overrides
transform
on theCollection
. Passnull
to disable transformation.
This works just like allow
, except it lets you
make sure that certain writes are definitely denied, even if there is an
allow
rule that says that they should be permitted.
When a client tries to write to a collection, the Meteor server first
checks the collection's deny
rules. If none of them return true then
it checks the collection's allow
rules. Meteor allows the write only
if no deny
rules return true
and at least one allow
rule returns
true
.
Server
collection.rawCollection()
Returns the Collection
object corresponding to this collection from the npm mongodb
driver module which is wrapped by Mongo.Collection
.
Server
collection.rawDatabase()
Returns the Db
object corresponding to this collection's database connection from the npm mongodb
driver module which is wrapped by Mongo.Collection
.
Cursors
To create a cursor, use find
. To access the documents in a
cursor, use forEach
, map
, or fetch
.
Anywhere
cursor.forEach(callback, [thisArg])
Call callback
once for each matching document, sequentially and synchronously.
Arguments
- callback Function
-
Function to call. It will be called with three arguments: the document, a 0-based index, and cursor itself.
- thisArg Any
-
An object which will be the value of
this
insidecallback
.
This interface is compatible with Array.forEach.
When called from a reactive computation, forEach
registers dependencies on
the matching documents.
Examples:
// Print the titles of the five top-scoring posts
var topPosts = Posts.find({}, {sort: {score: -1}, limit: 5});
var count = 0;
topPosts.forEach(function (post) {
console.log("Title of post " + count + ": " + post.title);
count += 1;
});
Anywhere
cursor.map(callback, [thisArg])
Map callback over all matching documents. Returns an Array.
Arguments
- callback Function
-
Function to call. It will be called with three arguments: the document, a 0-based index, and cursor itself.
- thisArg Any
-
An object which will be the value of
this
insidecallback
.
This interface is compatible with Array.map.
When called from a reactive computation, map
registers dependencies on
the matching documents.
On the server, if callback
yields, other calls to callback
may occur while
the first call is waiting. If strict sequential execution is necessary, use
forEach
instead.
Anywhere
cursor.fetch()
Return all matching documents as an Array.
When called from a reactive computation, fetch
registers dependencies on
the matching documents.
Anywhere
cursor.count()
Returns the number of documents that match a query.
Unlike the other functions, count
registers a dependency only on the
number of matching documents. (Updates that just change or reorder the
documents in the result set will not trigger a recomputation.)
Anywhere
cursor.observe(callbacks)
Watch a query. Receive callbacks as the result set changes.
Arguments
- callbacks Object
-
Functions to call to deliver the result set as it changes
Establishes a live query that invokes callbacks when the result of
the query changes. The callbacks receive the entire contents of the
document that was affected, as well as its old contents, if
applicable. If you only need to receive the fields that changed, see
observeChanges
.
callbacks
may have the following functions as properties:
- added(document) or
- addedAt(document, atIndex, before)
-
A new document
document
entered the result set. The new document appears at positionatIndex
. It is immediately before the document whose_id
isbefore
.before
will benull
if the new document is at the end of the results. - changed(newDocument, oldDocument) or
- changedAt(newDocument, oldDocument, atIndex)
-
The contents of a document were previously
oldDocument
and are nownewDocument
. The position of the changed document isatIndex
. - removed(oldDocument) or
- removedAt(oldDocument, atIndex)
-
The document
oldDocument
is no longer in the result set. It used to be at positionatIndex
. - movedTo(document, fromIndex, toIndex, before)
A document changed its position in the result set, from
fromIndex
totoIndex
(which is before the document with idbefore
). Its current contents isdocument
.
Use added
, changed
, and removed
when you don't care about the
order of the documents in the result set. They are more efficient than
addedAt
, changedAt
, and removedAt
.
Before observe
returns, added
(or addedAt
) will be called zero
or more times to deliver the initial results of the query.
observe
returns a live query handle, which is an object with a stop
method.
Call stop
with no arguments to stop calling the callback functions and tear
down the query. The query will run forever until you call this. If
observe
is called from a Tracker.autorun
computation, it is automatically
stopped when the computation is rerun or stopped.
(If the cursor was created with the option reactive
set to false, it will
only deliver the initial results and will not call any further callbacks;
it is not necessary to call stop
on the handle.)
Anywhere
cursor.observeChanges(callbacks)
Watch a query. Receive callbacks as the result set changes. Only the differences between the old and new documents are passed to the callbacks.
Arguments
- callbacks Object
-
Functions to call to deliver the result set as it changes
Establishes a live query that invokes callbacks when the result of
the query changes. In contrast to observe
,
observeChanges
provides only the difference between the old and new
result set, not the entire contents of the document that changed.
callbacks
may have the following functions as properties:
- added(id, fields) or
- addedBefore(id, fields, before)
-
A new document entered the result set. It has the
id
andfields
specified.fields
contains all fields of the document excluding the_id
field. The new document is before the document identified bybefore
, or at the end ifbefore
isnull
. - changed(id, fields)
The document identified by
id
has changed.fields
contains the changed fields with their new values. If a field was removed from the document then it will be present infields
with a value ofundefined
.- movedBefore(id, before)
The document identified by
id
changed its position in the ordered result set, and now appears before the document identified bybefore
.- removed(id)
The document identified by
id
was removed from the result set.
observeChanges
is significantly more efficient if you do not use
addedBefore
or movedBefore
.
Before observeChanges
returns, added
(or addedBefore
) will be called
zero or more times to deliver the initial results of the query.
observeChanges
returns a live query handle, which is an object with a stop
method. Call stop
with no arguments to stop calling the callback functions
and tear down the query. The query will run forever until you call this.
If
observeChanges
is called from a Tracker.autorun
computation, it is automatically
stopped when the computation is rerun or stopped.
(If the cursor was created with the option reactive
set to false, it will
only deliver the initial results and will not call any further callbacks;
it is not necessary to call stop
on the handle.)
Unlike observe
, observeChanges
does not provide absolute position
information (that is, atIndex
positions rather than before
positions.) This is for efficiency.
Example:
// Keep track of how many administrators are online.
var count = 0;
var query = Users.find({admin: true, onlineNow: true});
var handle = query.observeChanges({
added: function (id, user) {
count++;
console.log(user.name + " brings the total to " + count + " admins.");
},
removed: function () {
count--;
console.log("Lost one. We're now down to " + count + " admins.");
}
});
// After five seconds, stop keeping the count.
setTimeout(function () {handle.stop();}, 5000);
Anywhere
new Mongo.ObjectID([hexString])
import { Mongo } from 'meteor/mongo'
import { Mongo } from 'meteor/mongo'
Create a Mongo-style ObjectID
. If you don't specify a hexString
, the ObjectID
will generated randomly (not using MongoDB's ID construction rules).
Arguments
- hexString String
-
Optional. The 24-character hexadecimal contents of the ObjectID to create
Mongo.ObjectID
follows the same API as the Node MongoDB driver
ObjectID
class. Note that you must use the equals
method (or EJSON.equals
) to
compare them; the ===
operator will not work. If you are writing generic code
that needs to deal with _id
fields that may be either strings or ObjectID
s, use
EJSON.equals
instead of ===
to compare them.
ObjectID
values created by Meteor will not have meaningful answers to their getTimestamp
method, since Meteor currently constructs them fully randomly.
Mongo-Style Selectors
The simplest selectors are just a string or
Mongo.ObjectID
. These selectors match the
document with that value in its _id
field.
A slightly more complex form of selector is an object containing a set of keys that must match in a document:
// Matches all documents where deleted is false
{deleted: false}
// Matches all documents where the name and cognomen are as given
{name: "Rhialto", cognomen: "the Marvelous"}
// Matches every document
{}
But they can also contain more complicated tests:
// Matches documents where age is greater than 18
{age: {$gt: 18}}
// Also matches documents where tags is an array containing "popular"
{tags: "popular"}
// Matches documents where fruit is one of three possibilities
{fruit: {$in: ["peach", "plum", "pear"]}}
See the complete documentation.
Mongo-Style Modifiers
A modifier is an object that describes how to update a document in place by changing some of its fields. Some examples:
// Set the 'admin' property on the document to true
{$set: {admin: true}}
// Add 2 to the 'votes' property, and add "Traz"
// to the end of the 'supporters' array
{$inc: {votes: 2}, $push: {supporters: "Traz"}}
But if a modifier doesn't contain any $-operators, then it is instead interpreted as a literal document, and completely replaces whatever was previously in the database. (Literal document modifiers are not currently supported by validated updates.)
// Find the document with id "123", and completely replace it.
Users.update({_id: "123"}, {name: "Alice", friends: ["Bob"]});
See the full list of modifiers.
Sort Specifiers
Sorts may be specified using your choice of several syntaxes:
// All of these do the same thing (sort in ascending order by
// key "a", breaking ties in descending order of key "b")
[["a", "asc"], ["b", "desc"]]
["a", ["b", "desc"]]
{a: 1, b: -1}
The last form will only work if your JavaScript implementation preserves the order of keys in objects. Most do, most of the time, but it's up to you to be sure.
For local collections you can pass a comparator function which receives two document objects, and returns -1 if the first document comes first in order, 1 if the second document comes first, or 0 if neither document comes before the other. This is a Minimongo extension to MongoDB.
Field Specifiers
Queries can specify a particular set of fields to include or exclude from the result object.
To exclude specific fields from the result objects, the field specifier is a
dictionary whose keys are field names and whose values are 0
. All unspecified
fields are included.
Users.find({}, {fields: {password: 0, hash: 0}})
To include only specific fields in the result documents, use 1
as
the value. The _id
field is still included in the result.
Users.find({}, {fields: {firstname: 1, lastname: 1}})
With one exception, it is not possible to mix inclusion and exclusion styles:
the keys must either be all 1 or all 0. The exception is that you may specify
_id: 0
in an inclusion specifier, which will leave _id
out of the result
object as well. However, such field specifiers can not be used with
observeChanges
, observe
, cursors returned
from a publish function, or cursors used in
{{#each}}
in a template. They may be used with fetch
,
findOne
, forEach
, and map
.
Field
operators such as $
and $elemMatch
are not available on the client side
yet.
A more advanced example:
Users.insert({ alterEgos: [{ name: "Kira", alliance: "murderer" },
{ name: "L", alliance: "police" }],
name: "Yagami Light" });
Users.findOne({}, { fields: { 'alterEgos.name': 1, _id: 0 } });
// returns { alterEgos: [{ name: "Kira" }, { name: "L" }] }
See the MongoDB docs for details of the nested field rules and array behavior.
Session
Session
provides a global object on the client that you can use to
store an arbitrary set of key-value pairs. Use it to store things like
the currently selected item in a list.
What's special about Session
is that it's reactive. If
you call Session.get
("currentList")
from inside a template, the template will automatically be rerendered
whenever Session.set
("currentList", x)
is called.
Client
Session.set(key, value)
import { Session } from 'meteor/session'
import { Session } from 'meteor/session'
Set a variable in the session. Notify any listeners that the value
has changed (eg: redraw templates, and rerun any
Tracker.autorun
computations, that called
Session.get
on this key
.)
Arguments
- key String
-
The key to set, eg,
selectedItem
- value EJSON-able Object or undefined
-
The new value for
key
Example:
Tracker.autorun(function () {
Meteor.subscribe("chat-history", {room: Session.get("currentRoomId")});
});
// Causes the function passed to Tracker.autorun to be re-run, so
// that the chat-history subscription is moved to the room "home".
Session.set("currentRoomId", "home");
Session.set
can also be called with an object of keys and values, which is
equivalent to calling Session.set
individually on each key/value pair.
Session.set({
a: "foo",
b: "bar"
});
Client
Session.setDefault(key, value)
import { Session } from 'meteor/session'
import { Session } from 'meteor/session'
Set a variable in the session if it hasn't been set before.
Otherwise works exactly the same as Session.set
.
Arguments
- key String
-
The key to set, eg,
selectedItem
- value EJSON-able Object or undefined
-
The new value for
key
This is useful in initialization code, to avoid re-initializing a session variable every time a new version of your app is loaded.
Client
Session.get(key)
import { Session } from 'meteor/session'
import { Session } from 'meteor/session'
Get the value of a session variable. If inside a reactive
computation, invalidate the computation the next time the
value of the variable is changed by Session.set
. This
returns a clone of the session value, so if it's an object or an array,
mutating the returned value has no effect on the value stored in the
session.
Arguments
- key String
-
The name of the session variable to return
Example:
<!-- in main.html -->
<template name="main">
<p>We've always been at war with {{theEnemy}}.</p>
</template>
// in main.js
Template.main.helpers({
theEnemy: function () {
return Session.get("enemy");
}
});
Session.set("enemy", "Eastasia");
// Page will say "We've always been at war with Eastasia"
Session.set("enemy", "Eurasia");
// Page will change to say "We've always been at war with Eurasia"
Client
Session.equals(key, value)
import { Session } from 'meteor/session'
import { Session } from 'meteor/session'
Test if a session variable is equal to a value. If inside a reactive computation, invalidate the computation the next time the variable changes to or from the value.
Arguments
- key String
-
The name of the session variable to test
- value String, Number, Boolean, null, or undefined
-
The value to test against
If value is a scalar, then these two expressions do the same thing:
(1) Session.get("key") === value
(2) Session.equals("key", value)
... but the second one is always better. It triggers fewer invalidations (template redraws), making your program more efficient.
Example:
<template name="postsView">
{{! Show a dynamically updating list of items. Let the user click on an
item to select it. The selected item is given a CSS class so it
can be rendered differently. }}
{{#each posts}}
{{> postItem }}
{{/each}}
</template>
<template name="postItem">
<div class="{{postClass}}">{{title}}</div>
</template>
// in JS file
Template.postsView.helpers({
posts: function() {
return Posts.find();
}
});
Template.postItem.helpers({
postClass: function() {
return Session.equals("selectedPost", this._id) ?
"selected" : "";
}
});
Template.postItem.events({
'click': function() {
Session.set("selectedPost", this._id);
}
});
Using Session.equals here means that when the user clicks on an item and changes the selection, only the newly selected and the newly unselected items are re-rendered.
If Session.get had been used instead of Session.equals, then when the selection changed, all the items would be re-rendered.
For object and array session values, you cannot use Session.equals
; instead,
you need to use the underscore
package and write
_.isEqual(Session.get(key), value)
.
Accounts
The Meteor Accounts system builds on top of the userId
support in
publish
and methods
. The core
packages add the concept of user documents stored in the database, and
additional packages add secure password
authentication, integration with third party
login services, and a pre-built user
interface.
The basic Accounts system is in the accounts-base
package, but
applications typically include this automatically by adding one of the
login provider packages: accounts-password
, accounts-facebook
,
accounts-github
, accounts-google
, accounts-meetup
,
accounts-twitter
, or accounts-weibo
.
Read more about customizing user accounts in the Accounts article in the Meteor Guide.
Anywhere but publish functions
Meteor.user()
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Get the current user record, or null
if no user is logged in. A reactive data source.
Retrieves the user record for the current user from
the Meteor.users
collection.
On the client, this will be the subset of the fields in the document that
are published from the server (other fields won't be available on the
client). By default the server publishes username
, emails
, and
profile
(writable by user). See Meteor.users
for more on
the fields used in user documents.
Anywhere but publish functions
Meteor.userId()
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Get the current user id, or null
if no user is logged in. A reactive data source.
Anywhere
Meteor.users
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
A Mongo.Collection containing user documents.
This collection contains one document per registered user. Here's an example user document:
{
_id: "bbca5d6a-2156-41c4-89da-0329e8c99a4f", // Meteor.userId()
username: "cool_kid_13", // unique name
emails: [
// each email address can only belong to one user.
{ address<EMAIL_ADDRESS>verified: true },
{ address<EMAIL_ADDRESS>verified: false }
],
createdAt: Wed Aug 21 2013 15:16:52 GMT-0700 (PDT),
profile: {
// The profile is writable by the user by default.
name: "Joe Schmoe"
},
services: {
facebook: {
id: "709050", // facebook id
accessToken: "AAACCgdX7G2...AbV9AZDZD"
},
resume: {
loginTokens: [
{ token: "97e8c205-c7e4-47c9-9bea-8e2ccc0694cd",
when:<PHONE_NUMBER>048 }
]
}
}
}
A user document can contain any data you want to store about a user. Meteor treats the following fields specially:
username
: a unique String identifying the user.emails
: an Array of Objects with keysaddress
andverified
; an email address may belong to at most one user.verified
is a Boolean which is true if the user has verified the address with a token sent over email.createdAt
: the Date at which the user document was created.profile
: an Object which the user can create and update with any data. Do not store anything onprofile
that you wouldn't want the user to edit unless you have a deny rule on theMeteor.users
collection.services
: an Object containing data used by particular login services. For example, itsreset
field contains tokens used by forgot password links, and itsresume
field contains tokens used to keep you logged in between sessions.
Like all Mongo.Collections, you can access all documents on the server, but only those specifically published by the server are available on the client.
By default, the current user's username
, emails
and profile
are
published to the client. You can publish additional fields for the
current user with:
// server
Meteor.publish("userData", function () {
if (this.userId) {
return Meteor.users.find({_id: this.userId},
{fields: {'other': 1, 'things': 1}});
} else {
this.ready();
}
});
// client
Meteor.subscribe("userData");
If the autopublish package is installed, information about all users
on the system is published to all clients. This includes username
,
profile
, and any fields in services
that are meant to be public
(eg services.facebook.id
,
services.twitter.screenName
). Additionally, when using autopublish
more information is published for the currently logged in user,
including access tokens. This allows making API calls directly from
the client for services that allow this.
Users are by default allowed to specify their own profile
field with
Accounts.createUser
and modify it with
Meteor.users.update
. To allow users to edit additional fields, use
Meteor.users.allow
. To forbid users from making any modifications to
their user document:
Meteor.users.deny({update: function () { return true; }});
Client
Meteor.loggingIn()
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
True if a login method (such as Meteor.loginWithPassword
, Meteor.loginWithFacebook
, or Accounts.createUser
) is currently in progress. A reactive data source.
For example, the accounts-ui
package uses this to display an
animation while the login request is being processed.
Client
Meteor.logout([callback])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Log the user out.
Arguments
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
Client
Meteor.logoutOtherClients([callback])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Log out other clients logged in as the current user, but does not log out the client that calls this function.
Arguments
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
For example, when called in a user's browser, connections in that browser remain logged in, but any other browsers or DDP clients logged in as that user will be logged out.
Client
Meteor.loginWithPassword(user, password, [callback])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Log the user in with a password.
Arguments
- user Object or String
-
Either a string interpreted as a username or an email; or an object with a single key:
email
,username
orid
. Username or email match in a case insensitive manner. - password String
-
The user's password.
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
If there are multiple users with a username or email only differing in case, a case sensitive match is required. Although createUser
won't let you create users with ambiguous usernames or emails, this could happen with existing databases or if you modify the users collection directly.
This function is provided by the accounts-password
package. See the
Passwords section below.
Client
Meteor.loginWith<ExternalService>([options], [callback])
import { Meteor } from 'meteor/meteor'
import { Meteor } from 'meteor/meteor'
Log the user in using an external service.
Arguments
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure. The callback cannot be called if you are using the "redirect"loginStyle
, because the app will have reloaded in the meantime; try using client-side login hooks instead.
Options
- requestPermissions Array of Strings
-
A list of permissions to request from the user.
- requestOfflineToken Boolean
-
If true, asks the user for permission to act on their behalf when offline. This stores an additional offline token in the
services
field of the user document. Currently only supported with Google. - loginUrlParameters Object
-
Provide additional parameters to the authentication uri. Currently only supported with Google {@url https://developers.google.com/identity/protocols/OpenIDConnect#authenticationuriparameters}.
- loginHint String
-
An email address that the external service will use to pre-fill the login prompt. Currently only supported with Meteor developer accounts and Google accounts. If used with Google, the Google User ID can also be passed.
- loginStyle String
-
Login style ("popup" or "redirect", defaults to the login service configuration). The "popup" style opens the login page in a separate popup window, which is generally preferred because the Meteor application doesn't need to be reloaded. The "redirect" style redirects the Meteor application's window to the login page, and the login service provider redirects back to the Meteor application which is then reloaded. The "redirect" style can be used in situations where a popup window can't be opened, such as in a mobile UIWebView. The "redirect" style however relies on session storage which isn't available in Safari private mode, so the "popup" style will be forced if session storage can't be used.
- redirectUrl String
-
If using "redirect" login style, the user will be returned to this URL after authorisation has been completed.
Available functions are:
Meteor.loginWithMeteorDeveloperAccount
Meteor.loginWithFacebook
Meteor.loginWithGithub
Meteor.loginWithGoogle
Meteor.loginWithMeetup
Meteor.loginWithTwitter
Meteor.loginWithWeibo
These functions initiate the login process with an external service (eg: Facebook, Google, etc), using OAuth. When called they open a new pop-up window that loads the provider's login page. Once the user has logged in with the provider, the pop-up window is closed and the Meteor client logs in to the Meteor server with the information provided by the external service.
In addition to identifying the user to your application, some services
have APIs that allow you to take action on behalf of the user. To
request specific permissions from the user, pass the
requestPermissions
option the login function. This will cause the user
to be presented with an additional page in the pop-up dialog to permit
access to their data. The user's accessToken
— with permissions
to access the service's API — is stored in the services
field of
the user document. The supported values for requestPermissions
differ
for each login service and are documented on their respective developer
sites:
- Facebook: http://developers.facebook.com/docs/authentication/permissions/
- GitHub: http://developer.github.com/v3/oauth/#scopes
- Google: https://developers.google.com/accounts/docs/OAuth2Login#scopeparameter
- Meetup: http://www.meetup.com/meetup_api/auth/#oauth2-scopes
- Twitter, Weibo, Meteor developer accounts:
requestPermissions
currently not supported
External login services typically require registering and configuring
your application before use. The easiest way to do this is with the
accounts-ui
package which presents a step-by-step guide
to configuring each service. However, the data can be also be entered
manually in the ServiceConfiguration.configurations
collection, which
is exported by the service-configuration
package.
First, add the service configuration package:
meteor add service-configuration
Then, in your app:
ServiceConfiguration.configurations.upsert(
{ service: "weibo" },
{
$set: {
clientId: "1292962797",
loginStyle: "popup",
secret: "75a730b58f5691de5522789070c319bc"
}
}
);
Each external service has its own login provider package and login function. For example, to support GitHub login, run in your terminal:
meteor add accounts-github
and use the Meteor.loginWithGithub
function:
Meteor.loginWithGithub({
requestPermissions: ['user', 'public_repo']
}, function (err) {
if (err)
Session.set('errorMessage', err.reason || 'Unknown error');
});
Login service configuration is sent from the server to the client over DDP when
your app starts up; you may not call the login function until the configuration
is loaded. The function Accounts.loginServicesConfigured()
is a reactive data
source that will return true once the login service is configured; you should
not make login buttons visible or active until it is true.
Ensure that your $ROOT_URL
matches the authorized
domain and callback URL that you configure with the external service (for
instance, if you are running Meteor behind a proxy server, $ROOT_URL
should be
the externally-accessible URL, not the URL inside your proxy).
{{ currentUser }}
Calls Meteor.user(). Use {{#if currentUser}}
to check whether the user is logged in.
Client
Accounts.ui.config(options)
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Configure the behavior of {{> loginButtons}}
.
Options
- requestPermissions Object
-
Which permissions to request from the user for each external service.
- requestOfflineToken Object
-
To ask the user for permission to act on their behalf when offline, map the relevant external service to
true
. Currently only supported with Google. See Meteor.loginWithExternalService for more details. - forceApprovalPrompt Object
-
If true, forces the user to approve the app's permissions, even if previously approved. Currently only supported with Google.
- passwordSignupFields String
-
Which fields to display in the user creation form. One of '
USERNAME_AND_EMAIL
', 'USERNAME_AND_OPTIONAL_EMAIL
', 'USERNAME_ONLY
', or 'EMAIL_ONLY
' (default).
Example:
Accounts.ui.config({
requestPermissions: {
facebook: ['user_likes'],
github: ['user', 'repo']
},
requestOfflineToken: {
google: true
},
passwordSignupFields: 'USERNAME_AND_OPTIONAL_EMAIL'
});
Accounts (multi-server)
The accounts-base
package exports two constructors, called
AccountsClient
and AccountsServer
, which are used to create the
Accounts
object that is available on the client and the server,
respectively.
This predefined Accounts
object (along with similar convenience methods
of Meteor
, such as Meteor.logout
) is sufficient to
implement most accounts-related logic in Meteor apps. Nevertheless, these
two constructors can be instantiated more than once, to create multiple
independent connections between different accounts servers and their
clients, in more complicated authentication situations.
Client
new AccountsClient(options)
import { AccountsClient } from 'meteor/accounts-base'
import { AccountsClient } from 'meteor/accounts-base'
Constructor for the Accounts
object on the client.
Options
- connection Object
-
Optional DDP connection to reuse.
- ddpUrl String
-
Optional URL for creating a new DDP connection.
At most one of options.connection
and options.ddpUrl
should be
provided in any instantiation of AccountsClient
. If neither is provided,
Meteor.connection
will be used as the .connection
property of the
AccountsClient
instance.
Note that AccountsClient
is currently available only on the client, due
to its use of browser APIs such as window.localStorage
. In principle,
though, it might make sense to establish a client connection from one
server to another remote accounts server. Please let us
know
if you find yourself needing this server-to-server functionality.
Server
new AccountsServer(server)
import { AccountsServer } from 'meteor/accounts-base'
import { AccountsServer } from 'meteor/accounts-base'
Constructor for the Accounts
namespace on the server.
Arguments
- server Object
-
A server object such as
Meteor.server
.
The AccountsClient
and AccountsServer
classes share a common
superclass, AccountsCommon
. Methods defined on
AccountsCommon.prototype
will be available on both the client and the
server, via the predefined Accounts
object (most common) or any custom
accountsClientOrServer
object created using the AccountsClient
or
AccountsServer
constructors (less common).
Here are a few of those methods:
Anywhere but publish functions
accountsClientOrServer.userId()
Get the current user id, or null
if no user is logged in. A reactive data source.
Anywhere but publish functions
accountsClientOrServer.user()
Get the current user record, or null
if no user is logged in. A reactive data source.
Anywhere
accountsClientOrServer.config(options)
Set global accounts options.
Options
- sendVerificationEmail Boolean
-
New users with an email address will receive an address verification email.
- forbidClientAccountCreation Boolean
-
Calls to
createUser
from the client will be rejected. In addition, if you are using accounts-ui, the "Create account" link will not be available. - restrictCreationByEmailDomain String or Function
-
If set to a string, only allows new users if the domain part of their email address matches the string. If set to a function, only allows new users if the function returns true. The function is passed the full email address of the proposed new user. Works with password-based sign-in and external services that expose email addresses (Google, Facebook, GitHub). All existing users still can log in after enabling this option. Example:
Accounts.config({ restrictCreationByEmailDomain: 'school.edu' })
. - loginExpirationInDays Number
-
The number of days from when a user logs in until their token expires and they are logged out. Defaults to 90. Set to
null
to disable login expiration. - oauthSecretKey String
-
When using the
oauth-encryption
package, the 16 byte key using to encrypt sensitive account credentials in the database, encoded in base64. This option may only be specifed on the server. See packages/oauth-encryption/README.md for details.
These methods are defined on AccountsClient.prototype
, and are thus
available only on the client:
Client
accountsClient.loggingIn()
True if a login method (such as Meteor.loginWithPassword
, Meteor.loginWithFacebook
, or Accounts.createUser
) is currently in progress. A reactive data source.
Client
accountsClient.logout([callback])
Log the user out.
Arguments
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
Client
accountsClient.logoutOtherClients([callback])
Log out other clients logged in as the current user, but does not log out the client that calls this function.
Arguments
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
These methods are defined on AccountsServer.prototype
, and are thus
available only on the server:
Server
accountsServer.validateNewUser(func)
Set restrictions on new user creation.
Arguments
- func Function
-
Called whenever a new user is created. Takes the new user object, and returns true to allow the creation or false to abort.
This can be called multiple times. If any of the functions return false
or
throw an error, the new user creation is aborted. To set a specific error
message (which will be displayed by accounts-ui
), throw a new
Meteor.Error
.
Example:
// Validate username, sending a specific error message on failure.
Accounts.validateNewUser(function (user) {
if (user.username && user.username.length >= 3)
return true;
throw new Meteor.Error(403, "Username must have at least 3 characters");
});
// Validate username, without a specific error message.
Accounts.validateNewUser(function (user) {
return user.username !== "root";
});
If the user is being created as part of a login attempt from a client (eg,
calling Accounts.createUser
from the client, or
logging in for the first time with an external
service), these callbacks are called before
the Accounts.validateLoginAttempt
callbacks. If these callbacks succeed but those fail, the user will still be
created but the connection will not be logged in as that user.
Server
accountsServer.onCreateUser(func)
Customize new user creation.
Arguments
- func Function
-
Called whenever a new user is created. Return the new user object, or throw an
Error
to abort the creation.
Use this when you need to do more than simply accept or reject new user creation. With this function you can programatically control the contents of new user documents.
The function you pass will be called with two arguments: options
and
user
. The options
argument comes
from Accounts.createUser
for
password-based users or from an external service login flow. options
may come
from an untrusted client so make sure to validate any values you read from
it. The user
argument is created on the server and contains a
proposed user object with all the automatically generated fields
required for the user to log in, including the _id
.
The function should return the user document (either the one passed in or a
newly-created object) with whatever modifications are desired. The returned
document is inserted directly into the Meteor.users
collection.
The default create user function simply copies options.profile
into
the new user document. Calling onCreateUser
overrides the default
hook. This can only be called once.
Example:
// Support for playing D&D: Roll 3d6 for dexterity
Accounts.onCreateUser(function(options, user) {
var d6 = function () { return Math.floor(Random.fraction() * 6) + 1; };
user.dexterity = d6() + d6() + d6();
// We still want the default hook's 'profile' behavior.
if (options.profile)
user.profile = options.profile;
return user;
});
Server
accountsServer.validateLoginAttempt(func)
Validate login attempts.
Arguments
- func Function
-
Called whenever a login is attempted (either successful or unsuccessful). A login can be aborted by returning a falsy value or throwing an exception.
Call validateLoginAttempt
with a callback to be called on login
attempts. It returns an object with a single method, stop
. Calling
stop()
unregisters the callback.
When a login attempt is made, the registered validate login callbacks are called with a single argument, the attempt info object:
- type String
The service name, such as "password" or "twitter".
- allowed Boolean
Whether this login is allowed and will be successful (if not aborted by any of the validateLoginAttempt callbacks). False if the login will not succeed (for example, an invalid password or the login was aborted by a previous validateLoginAttempt callback).
- error Exception
When
allowed
is false, the exception describing why the login failed. It will be aMeteor.Error
for failures reported to the user (such as invalid password), and can be a another kind of exception for internal errors.- user Object
When it is known which user was attempting to login, the Meteor user object. This will always be present for successful logins.
- connection Object
The
connection
object the request came in on. SeeMeteor.onConnection
for details.- methodName String
The name of the Meteor method being used to login.
- methodArguments Array
An array of the arguments passed to the login method.
A validate login callback must return a truthy value for the login to
proceed. If the callback returns a falsy value or throws an
exception, the login is aborted. Throwing a Meteor.Error
will
report the error reason to the user.
All registered validate login callbacks are called, even if one of the callbacks
aborts the login. The later callbacks will see the allowed
field set to
false
since the login will now not be successful. This allows later callbacks
to override an error from a previous callback; for example, you could override
the "Incorrect password" error with a different message.
Validate login callbacks that aren't explicitly trying to override a previous error generally have no need to run if the attempt has already been determined to fail, and should start with
if (!attempt.allowed)
return false;
Anywhere
accountsClientOrServer.onLogin(func)
Register a callback to be called after a login attempt succeeds.
Arguments
- func Function
-
The callback to be called when login is successful.
See description of AccountsCommon#onLoginFailure for details.
Anywhere
accountsClientOrServer.onLoginFailure(func)
Register a callback to be called after a login attempt fails.
Arguments
- func Function
-
The callback to be called after the login has failed.
Either the onLogin
or the onLoginFailure
callbacks will be called
for each login attempt. The onLogin
callbacks are called after the
user has been successfully logged in. The onLoginFailure
callbacks are
called after a login attempt is denied.
These functions return an object with a single method, stop
. Calling
stop()
unregisters the callback.
On the server, the callbacks get a single argument, the same attempt info
object as validateLoginAttempt
. On the
client, no arguments are passed.
Rate Limiting
By default, there are rules added to the DDPRateLimiter
that rate limit logins, new user registration and password reset calls to a
limit of 5 requests per 10 seconds per session.
These rate limiting rules can be removed by calling
Accounts.removeDefaultRateLimit()
. Please see the
DDPRateLimiter
docs for more information.
Passwords
The accounts-password
package contains a full system for password-based
authentication. In addition to the basic username and password-based
sign-in process, it also supports email-based sign-in including
address verification and password recovery emails.
The Meteor server stores passwords using the bcrypt algorithm. This helps protect against embarrassing password leaks if the server's database is compromised.
To add password support to your application, run this command in your terminal:
meteor add accounts-password
You can construct your own user interface using the
functions below, or use the accounts-ui
package to
include a turn-key user interface for password-based sign-in.
Anywhere
Accounts.createUser(options, [callback])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Create a new user.
Arguments
- callback Function
-
Client only, optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
Options
- username String
-
A unique name for this user.
- email String
-
The user's email address.
- password String
-
The user's password. This is not sent in plain text over the wire.
- profile Object
-
The user's profile, typically including the
name
field.
On the client, this function logs in as the newly created user on successful completion. On the server, it returns the newly created user id.
On the client, you must pass password
and at least one of username
or
email
— enough information for the user to be able to log in again
later. If there are existing users with a username or email only differing in
case, createUser
will fail. On the server, you do not need to specify
password
, but the user will not be able to log in until it has a password (eg,
set with Accounts.setPassword
).
To create an account without a password on the server and still let the
user pick their own password, call createUser
with the email
option
and then
call Accounts.sendEnrollmentEmail
. This
will send the user an email with a link to set their initial password.
By default the profile
option is added directly to the new user document. To
override this behavior, use Accounts.onCreateUser
.
This function is only used for creating users with passwords. The external service login flows do not use this function.
Managing usernames and emails
Instead of modifying documents in the Meteor.users
collection
directly, use these convenience functions which correctly check for case
insensitive duplicates before updates.
Server
Accounts.setUsername(userId, newUsername)
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Change a user's username. Use this instead of updating the database directly. The operation will fail if there is an existing user with a username only differing in case.
Arguments
- userId String
-
The ID of the user to update.
- newUsername String
-
A new username for the user.
Server
Accounts.addEmail(userId, newEmail, [verified])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Add an email address for a user. Use this instead of directly updating the database. The operation will fail if there is a different user with an email only differing in case. If the specified user has an existing email only differing in case however, we replace it.
Arguments
- userId String
-
The ID of the user to update.
- newEmail String
-
A new email address for the user.
- verified Boolean
-
Optional - whether the new email address should be marked as verified. Defaults to false.
By default, an email address is added with { verified: false }
. Use
Accounts.sendVerificationEmail
to send an
email with a link the user can use verify their email address.
Server
Accounts.removeEmail(userId, email)
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Remove an email address for a user. Use this instead of updating the database directly.
Arguments
- userId String
-
The ID of the user to update.
- email String
-
The email address to remove.
Client
Accounts.verifyEmail(token, [callback])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Marks the user's email address as verified. Logs the user in afterwards.
Arguments
- token String
-
The token retrieved from the verification URL.
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
This function accepts tokens passed into the callback registered with
Accounts.onEmailVerificationLink
.
Server
Accounts.findUserByUsername(username)
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Finds the user with the specified username. First tries to match username case sensitively; if that fails, it tries case insensitively; but if more than one user matches the case insensitive search, it returns null.
Arguments
- username String
-
The username to look for
Server
Accounts.findUserByEmail(email)
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Finds the user with the specified email. First tries to match email case sensitively; if that fails, it tries case insensitively; but if more than one user matches the case insensitive search, it returns null.
Arguments
- email String
-
The email address to look for
Managing passwords
Use the below functions to initiate password changes or resets from the server or the client.
Client
Accounts.changePassword(oldPassword, newPassword, [callback])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Change the current user's password. Must be logged in.
Arguments
- oldPassword String
-
The user's current password. This is not sent in plain text over the wire.
- newPassword String
-
A new password for the user. This is not sent in plain text over the wire.
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
Client
Accounts.forgotPassword(options, [callback])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Request a forgot password email.
Arguments
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
Options
- email String
-
The email address to send a password reset link.
This triggers a call
to Accounts.sendResetPasswordEmail
on the server. When the user visits the link in this email, the callback
registered with Accounts.onResetPasswordLink
will be called.
If you are using the accounts-ui
package, this is handled
automatically. Otherwise, it is your responsibility to prompt the user for the
new password and call resetPassword
.
Client
Accounts.resetPassword(token, newPassword, [callback])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Reset the password for a user using a token received in email. Logs the user in afterwards.
Arguments
- token String
-
The token retrieved from the reset password URL.
- newPassword String
-
A new password for the user. This is not sent in plain text over the wire.
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
This function accepts tokens passed into the callbacks registered with
AccountsClient#onResetPasswordLink
and
Accounts.onEnrollmentLink
.
Server
Accounts.setPassword(userId, newPassword, [options])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Forcibly change the password for a user.
Arguments
- userId String
-
The id of the user to update.
- newPassword String
-
A new password for the user.
Options
- logout Object
-
Logout all current connections with this userId (default: true)
Sending emails
Server
Accounts.sendResetPasswordEmail(userId, [email])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Send an email with a link the user can use to reset their password.
Arguments
- userId String
-
The id of the user to send email to.
- email String
-
Optional. Which address of the user's to send the email to. This address must be in the user's
emails
list. Defaults to the first email in the list.
When the user visits the link in this email, the callback registered with
AccountsClient#onResetPasswordLink
will be called.
To customize the contents of the email, see
Accounts.emailTemplates
.
Server
Accounts.sendEnrollmentEmail(userId, [email])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Send an email with a link the user can use to set their initial password.
Arguments
- userId String
-
The id of the user to send email to.
- email String
-
Optional. Which address of the user's to send the email to. This address must be in the user's
emails
list. Defaults to the first email in the list.
When the user visits the link in this email, the callback registered with
Accounts.onEnrollmentLink
will be called.
To customize the contents of the email, see
Accounts.emailTemplates
.
Server
Accounts.sendVerificationEmail(userId, [email])
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Send an email with a link the user can use verify their email address.
Arguments
- userId String
-
The id of the user to send email to.
- email String
-
Optional. Which address of the user's to send the email to. This address must be in the user's
emails
list. Defaults to the first unverified email in the list.
When the user visits the link in this email, the callback registered with
Accounts.onEmailVerificationLink
will
be called.
To customize the contents of the email, see
Accounts.emailTemplates
.
Client
Accounts.onResetPasswordLink
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Register a function to call when a reset password link is clicked
in an email sent by
Accounts.sendResetPasswordEmail
.
This function should be called in top-level code, not inside
Meteor.startup()
.
Arguments
- callback Function
-
The function to call. It is given two arguments:
token
: A password reset token that can be passed toAccounts.resetPassword
.done
: A function to call when the password reset UI flow is complete. The normal login process is suspended until this function is called, so that the password for user A can be reset even if user B was logged in.
Client
Accounts.onEnrollmentLink
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Register a function to call when an account enrollment link is
clicked in an email sent by
Accounts.sendEnrollmentEmail
.
This function should be called in top-level code, not inside
Meteor.startup()
.
Arguments
- callback Function
-
The function to call. It is given two arguments:
token
: A password reset token that can be passed toAccounts.resetPassword
to give the newly enrolled account a password.done
: A function to call when the enrollment UI flow is complete. The normal login process is suspended until this function is called, so that user A can be enrolled even if user B was logged in.
Client
Accounts.onEmailVerificationLink
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Register a function to call when an email verification link is
clicked in an email sent by
Accounts.sendVerificationEmail
.
This function should be called in top-level code, not inside
Meteor.startup()
.
Arguments
- callback Function
-
The function to call. It is given two arguments:
token
: An email verification token that can be passed toAccounts.verifyEmail
.done
: A function to call when the email verification UI flow is complete. The normal login process is suspended until this function is called, so that the user can be notified that they are verifying their email before being logged in.
Server
Accounts.emailTemplates
import { Accounts } from 'meteor/accounts-base'
import { Accounts } from 'meteor/accounts-base'
Options to customize emails sent from the Accounts system.
This is an Object
with several fields that are used to generate text/html
for the emails sent by sendResetPasswordEmail
, sendEnrollmentEmail
,
and sendVerificationEmail
.
Override fields of the object by assigning to them:
from
: AString
with an RFC5322 From address. By default, the email is sent<EMAIL_ADDRESS>. If you wish to receive email from users asking for help with their account, be sure to set this to an email address that you can receive email at.siteName
: The public name of your application. Defaults to the DNS name of the application (eg:awesome.meteor.com
).headers
: AnObject
for custom email headers as described inEmail.send
.resetPassword
: AnObject
with the fields:from
: AFunction
used to override thefrom
address defined by theemailTemplates.from
field.subject
: AFunction
that takes a user object and returns aString
for the subject line of a reset password email.text
: An optionalFunction
that takes a user object and a url, and returns the body text for a reset password email.html
: An optionalFunction
that takes a user object and a url, and returns the body html for a reset password email.
enrollAccount
: Same asresetPassword
, but for initial password setup for new accounts.verifyEmail
: Same asresetPassword
, but for verifying the users email address.
Example:
Accounts.emailTemplates.siteName = "AwesomeSite";
Accounts.emailTemplates.from = "AwesomeSite Admin<EMAIL_ADDRESS>Accounts.emailTemplates.enrollAccount.subject = function (user) {
return "Welcome to Awesome Town, " + user.profile.name;
};
Accounts.emailTemplates.enrollAccount.text = function (user, url) {
return "You have been selected to participate in building a better future!"
+ " To activate your account, simply click the link below:\n\n"
+ url;
};
Templates
When you write a template as <template name="foo"> ... </template>
in an HTML file in your app, Meteor generates a
"template object" named Template.foo
. Note that template name cannot
contain hyphens and other special characters.
The same template may occur many times on a page, and these occurrences are called template instances. Template instances have a life cycle of being created, put into the document, and later taken out of the document and destroyed. Meteor manages these stages for you, including determining when a template instance has been removed or replaced and should be cleaned up. You can associate data with a template instance, and you can access its DOM nodes when it is in the document.
Read more about templates and how to use them in the Spacebars package README and the Blaze article in the Meteor Guide.
Client
Template.myTemplate.events(eventMap)
import { Template } from 'meteor/templating'
import { Template } from 'meteor/templating'
Specify event handlers for this template.
Arguments
- eventMap Event Map
-
Event handlers to associate with this template.
Declare event handlers for instances of this template. Multiple calls add new event handlers in addition to the existing ones.
See Event Maps for a detailed description of the event map format and how event handling works in Meteor.
Client
Template.myTemplate.helpers(helpers)
import { Template } from 'meteor/templating'
import { Template } from 'meteor/templating'
Specify template helpers available to this template.
Arguments
- helpers Object
-
Dictionary of helper functions by name.
Each template has a local dictionary of helpers that are made available to it, and this call specifies helpers to add to the template's dictionary.
Example:
Template.myTemplate.helpers({
foo() {
return Session.get("foo");
}
});
Now you can invoke this helper with {{foo}}
in the template defined
with <template name="myTemplate">
.
Helpers can accept positional and keyword arguments:
Template.myTemplate.helpers({
displayName(firstName, lastName, keyword) {
var prefix = keyword.hash.title ? keyword.hash.title + " " : "";
return prefix + firstName + " " + lastName;
}
});
Then you can call this helper from template like this:
{{displayName "John" "Doe" title="President"}}
You can learn more about arguments to helpers in Spacebars Readme.
Under the hood, each helper starts a new
Tracker.autorun
. When its reactive
dependencies change, the helper is rerun. Helpers depend on their data
context, passed arguments and other reactive data sources accessed during
execution.
To create a helper that can be used in any template, use
Template.registerHelper
.
Client
Template.myTemplate.onRendered
import { Template } from 'meteor/templating'
import { Template } from 'meteor/templating'
Register a function to be called when an instance of this template is inserted into the DOM.
Arguments
- callback Function
-
A function to be added as a callback.
Callbacks added with this method are called once when an instance of Template.myTemplate is rendered into DOM nodes and put into the document for the first time.
In the body of a callback, this
is a template instance
object that is unique to this occurrence of the template and persists across
re-renderings. Use the onCreated
and onDestroyed
callbacks to perform
initialization or clean-up on the object.
Because your template has been rendered, you can use functions like
this.findAll
which look at its DOM nodes.
This can be a good place to apply any DOM manipulations you want, after the template is rendered for the first time.
<template name="myPictures">
<div class="container">
{{#each pictures}}
<img class="item" src="/{{.}}"/>
{{/each}}
</div>
</template>
Template.myPictures.onRendered(function () {
// Use the Packery jQuery plugin
this.$('.container').packery({
itemSelector: '.item',
gutter: 10
});
});
Client
Template.myTemplate.onCreated
import { Template } from 'meteor/templating'
import { Template } from 'meteor/templating'
Register a function to be called when an instance of this template is created.
Arguments
- callback Function
-
A function to be added as a callback.
Callbacks added with this method are called before your template's logic is
evaluated for the first time. Inside a callback, this
is the new template
instance object. Properties you set on this object will be
visible from the callbacks added with onRendered
and onDestroyed
methods and
from event handlers.
These callbacks fire once and are the first group of callbacks to fire.
Handling the created
event is a useful way to set up values on template
instance that are read from template helpers using Template.instance()
.
Template.myPictures.onCreated(function () {
// set up local reactive variables
this.highlightedPicture = new ReactiveVar(null);
// register this template within some central store
GalleryTemplates.push(this);
});
Client
Template.myTemplate.onDestroyed
import { Template } from 'meteor/templating'
import { Template } from 'meteor/templating'
Register a function to be called when an instance of this template is removed from the DOM and destroyed.
Arguments
- callback Function
-
A function to be added as a callback.
These callbacks are called when an occurrence of a template is taken off
the page for any reason and not replaced with a re-rendering. Inside
a callback, this
is the template instance object
being destroyed.
This group of callbacks is most useful for cleaning up or undoing any external
effects of created
or rendered
groups. This group fires once and is the last
callback to fire.
Template.myPictures.onDestroyed(function () {