diff --git a/docs/client/api.html b/docs/client/api.html
index 7f9829e9d6b..cd348b8b104 100644
--- a/docs/client/api.html
+++ b/docs/client/api.html
@@ -8,7 +8,7 @@
The Meteor API
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
+Meteor Core
{{> api_box is_client}}
{{> api_box is_server}}
@@ -28,46 +28,36 @@ Meteor
});
}
-{{> api_box setTimeout}}
-{{> api_box setInterval}}
-{{> api_box clearTimeout}}
-{{> api_box clearInterval}}
-
-On the server, native functions like `setTimeout()` that schedule future
-callbacks need to be wrapped so that they create the right thread
-context for your code. You don't have to worry about the details; just
-use these equivalents instead of the native functions.
+Publish and subscribe
-{{#warning}}
-We will probably override the native server functions in a future
-release, obviating the need for these wrappers.
-{{/warning}}
+These functions control how Meteor servers publish sets of records and
+how clients can subscribe to those sets.
{{> api_box publish}}
-To publish data to clients, call `Meteor.publish()` on the server with
-two parameters: the name of the data set, and a *publish function*
+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.
-{{#warning}}
-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.
-{{/warning}}
-
-If your publish function returns a collection cursor, Meteor will watch
-publish each result of that cursor and then keep the client up to date
-as the cursor's results change (by running `observe()` on your cursor).
-When a client unsubscribes, Meteor will unset all of the client's data
-for you.
+Publish functions can return a
+[`Collection.Cursor`](#meteor_collection_cursor), in which case Meteor
+will publish that cursor's documents.
// server: publish the rooms collection, minus secret info.
Meteor.publish("rooms", function () {
return Rooms.find({}, {fields: {secret_info: false}});
});
-To explicitly set and unset attributes on a client, use
-these methods provided by `this` in your publish function:
+Otherwise, the publish function can set and unset
+individual record attributes on a client, use these methods provided by
+`this` in your publish function.
+
+
+
+In particular, if you use observe() to watch changes to the database, be
+sure to call `this.flush` from inside your observe callbacks. Methods
+that update the database are considered finished when the observe
+callbacks return.
Example:
@@ -99,54 +89,48 @@ Meteor
});
});
+{{#warning}}
+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.
+{{/warning}}
+
{{> api_box subscription_set}}
{{> api_box subscription_unset}}
{{> api_box subscription_complete}}
{{> api_box subscription_flush}}
-{{#warning}}
-If you use observe() to watch changes to the database, be sure to call `this.flush()`
-from inside your observe callbacks. Methods that update the database
-are considered finished when the observe callbacks return.
-{{/warning}}
-
{{> api_box subscription_onStop}}
+
+If you call [`observe`](#cursor_observe) in your publish handler, this
+is the place to stop the observes.
+
{{> api_box subscription_stop}}
{{> api_box subscribe}}
-When you subscribe to a set, the client will store the attributes
-published by the server in local Minimongo collections, with the same
-name as the `collection` argument to `set()`. Meteor will queue
-incoming attributes until you declare the `Meteor.Collection()` on the
-client with the matching collection name.
+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 to `set`.
+Meteor will queue incoming attributes until you declare the
+`Meteor.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 documents until ...
+ // client queues incoming players records until ...
...
Players = new Meteor.Collection("players");
-If more than one subscription sends overlapping attributes (same
-collection name, document ID, and attribute name), Meteor will *shadow*
-all but one of the values. The value in Minimongo will be that from the
-*first* subscription the client activated. (Even if it is not the first
-to send the duplicated attribute.)
-
-When you stop a subscription, Meteor removes all the data that came from
-that subscription. If any attributes shadowed a different
-subscription's data, Meteor chooses the next-highest priority
-subscription.
+If more than one subscription sends conflicting values for an attribute
+(same collection name, document ID, and attribute name), then the value
+on the client will be that from the *first* subscription the client
+activated. (Even if it is not the first to send the duplicated
+attribute.)
-{{#warning}}
-In a future release we will give you better control over subscription
-priorities.
-{{/warning}}
-
-If all of the attributes in a Minimongo document are removed, Meteor
+If all of the attributes in a document are removed, Meteor
will remove the (now empty) document. If you want to publish empty
documents, just use a placeholder attribute.
@@ -154,7 +138,19 @@ Meteor
{{> api_box autosubscribe}}
-The easiest way to explain `autosubscribe()` is to show an example.
+`func` will be run immediately, and while it runs,
+records will be kept of the subscriptions it makes
+(via [`Meteor.subscribe`](#subscribe)) and the data it uses
+(including calls to [`Session.get`](#get)
+and [`collection.find`](#find)).
+
+Whenever the used data changes, the subscriptions will be cancelled and
+`func` will be re-run to make replacement subscriptions.
+`Meteor.autosubscribe` will automatically stop the old subscription.
+It's not necessary to call `stop` on subscriptions made from inside
+`Meteor.autosubscribe`.
+
+Example:
// Subscribe to the chat messages in the current room. Automatically
// update the subscription whenever the current room changes.
@@ -162,19 +158,9 @@ Meteor
Meteor.subscribe("chat", {room: Session.get("current-room");});
});
-`func` will be run immediately, and while it runs,
-records will be kept of the subscriptions it makes
-(via [`Meteor.subscribe`](#subscribe)) and the data it uses
-(including calls to [`Session.get`](#get)
-and [`collection.find`](#find)).
+
-Whenever the used data changes, the subscriptions will be cancelled
-and `func` will be re-run to make replacement subscriptions.
-
-{{#warning}}
-It's not necessary to call `stop` on subscriptions made
-from inside `Meteor.autosubscribe`.
-{{/warning}}
+Methods are remote functions that Meteor clients can invoke.
{{> api_box methods}}
@@ -186,46 +172,35 @@ Meteor
if (you want to throw an error)
throw new Meteor.Error(404, "Can't find my pants");
return "some return value";
+ },
+
+ bar: function () {
+ // .. do other stuff ..
+ return "baz";
}
});
-Calling `methods()` on the server defines JavaScript functions that can
-be called remotely by clients. When a client invokes a method, it sends
-a message to the server to run the method, along with the parameters.
-The server eventually sends back a result.
-
-Methods are always written in synchronous style. Their caller will not
-receive a response until they return (either normally, or by throwing an
-exception.) But this is not a limitation, since we have fibers on the
-server, so you can set up your control flow however you want.
-
-Calling `methods()` on the client defines *stub* functions associated
-with server methods of the same name. When a client invokes a server
-method, it will run that method's stub in parallel, if one is defined.
-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. On the client, the return value of a stub is
-ignored. (If a stub throws an exception, including a `Meteor.Error`
-exception, that will be logged to the console.)
-
-Inside your method invocation, this is bound to a method
-invocation object, which provides the following:
+Calling `methods` on the server defines functions that can be called
+remotely by clients. They should return a value or throw an exception.
+Inside your method invocation, `this` is bound to a method invocation
+object, which provides the following:
* `is_simulation`: a boolean value, true if this invocation is a stub.
-* `unblock()`: when called, allows the next method from this client to
+* `unblock`: when called, allows the next method from this client to
begin running.
-{{#warning}}
-When authentication is available, the current user will be in
-`this.user`.
-{{/warning}}
-
-{{> api_box error}}
+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.
-Methods can throw any kind of exception, not just `Meteor.Error`. But
-`Meteor.Error` is the only kind of error that can go across the wire. If
-you throw a different exception, then it will be mapped to
-`Meteor.Error(500, "Internal server error")` on the wire.
+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.
{{> api_box method_invocation_is_simulation}}
@@ -233,23 +208,33 @@ Meteor
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
+returns. However, you can change this by calling `this.unblock`. This
will allow the N+1th invocation to start running in a new fiber.
+{{> api_box error}}
+
+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
+`Meteor.Error(500, "Internal server error")` on the wire.
+
{{> api_box call}}
-On both the client and server, if you include a callback function as the
-last argument (which can't be an argument to the method, since functions
-aren't serializeable), the method will run asynchronously: it will
-return nothing in particular and will not throw an execption. When the
-method is complete (which may or may not happen before `Meteor.call`
-returns), the callback will be called. If an error was thrown, then
-`err` will be the exception object (possibly mapped to `Meteor.Error`,
-just like above.) Otherwise, the return value (possibly undefined) will
-be in `result`.
+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.
- // async
- Meteor.call('foo', 1, 2, function (err, result) { ... } );
+If you include a callback function as the last argument (which can't be
+an argument to the method, since functions aren't serializeable), the
+method will run asynchronously: it will return nothing in particular and
+will not throw an execption. 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
@@ -257,11 +242,11 @@ Meteor
threw an exception. (Possibly mapped to 500 Server Error if the
exception happened remotely and it was not a `Meteor.Error` exception.)
- // sync
+ // 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
+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.
@@ -284,8 +269,13 @@ Meteor
{{> api_box apply}}
-`Meteor.apply()` is just like `Meteor.call()`, but it takes a method
-name and an array of arguments.
+`Meteor.apply` is just like `Meteor.call`, but it allows the
+arguments to be passed as an array.
+
+Server connections
+
+These functions manage and inspect the network connection between the
+Meteor client and server.
{{> api_box status}}
@@ -295,15 +285,16 @@ Meteor
- connected
Boolean
-- True if currently connected to the server. If false, changes will
- be queued up until the connection is reestablished.
+- True if currently connected to the server. If false, changes and
+ method invocations will be queued up until the connection is
+ reestablished.
- status
String
-- Text string describing the current reconnection status. The possible
- values are "`connected`" (the connection is up and
- running), "`connecting`" (disconnected and trying to open a
- new connection), and "`waiting`" (failed to connect and
+
- 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), and waiting
(failed to connect and
waiting to try to reconnect).
- retry_count
@@ -315,26 +306,23 @@
Meteor
Number or undefined
- The estimated time of the next reconnection attempt. To turn this
into an interval until the next reconnection, use
- "`retry_time - (new Date()).getTime()`". This key will
- be set only when `status` is `"waiting"`.
+
retry_time - (new Date()).getTime()
. This key will
+ be set only when status
is waiting
.
Instead of using callbacks to notify you on changes, this is
a reactive data source. You can use it in a
-template or invalidation
+template or invalidation
context to get realtime updates.
{{> api_box reconnect}}
{{> api_box connect}}
-By default, every Meteor client is connected to its server. When you
-call `Meteor.subscribe`, `Meteor.status`, `Meteor.call`, and
-`Meteor.apply`, you are referring to the connection back to that default server.
-Your client and server can open additional connections to other Meteor
-servers by calling `Meteor.connect()`, passing the URL of the
-server endpoint. `Meteor.connect` returns an object which provides:
+To call methods on another Meteor application or subscribe to its data
+sets, call `Meteor.connect` with the URL of the application.
+`Meteor.connect` returns an object which provides:
* `subscribe`
* `methods` (to define stubs)
@@ -343,70 +331,19 @@ Meteor
* `status`
* `reconnect`
+When you call `Meteor.subscribe`, `Meteor.status`, `Meteor.call`, and
+`Meteor.apply`, you are using a connection back to that default
+server.
+
{{#warning}}
-`Meteor.connect` is not currently implemented on the
-server, so you can't call remote Meteor methods on the server today.
-This will change, though: you'll be able to connect to a remote server
-and do synchronous method calls, and Meteor will use
-fibers to run them synchronously for you.
+In this release, `Meteor.connect` can only be called on the client.
+Servers can not yet connect to other servers.
{{/warning}}
-{{> api_box flush }}
-
-Normally, when you make changes (like writing to the database),
-their impact (like updating the DOM) is delayed until the system is
-idle. This keeps things predictable — you can know that the DOM
-won't go changing out from under your code as it runs. It's also one
-of the things that makes Meteor fast.
-
-`Meteor.flush()` forces all of the pending reactive updates to complete
-(for example, it ensures the DOM has been updated with your recent
-database changes.) Call `flush()` to apply those pending changes
-immediately. The main use for this is to make sure the DOM has been
-brought up to date with your latest changes, so you can manually
-manipulate it with jQuery or the like.
-
-When you call `flush()`, any auto-updating DOM elements that are not on
-the screen may be cleaned up (meaning that Meteor will stop tracking and
-updating the elements, so that the browser's garbage collector can
-delete them.) So, if you manually call `flush()`, you need to make sure
-that any auto-updating elements that you have created with templates, or
-by calling [`Meteor.ui.render`](#render), have already been inserted in
-the main DOM tree.
-
-Technically speaking, `flush()` calls the [invalidation
-callbacks](#on_invalidate) on every [reactive context](#context) that
-has been [invalidated](#invalidate), but hasn't yet has its callbacks
-called. If the invalidation callbacks invalidate still more contexts,
-flush keeps flushing until everything is totally settled. The DOM
-elements are cleaned up because of logic in
-[`Meteor.ui.render`](#render) that works through invalidations.
-
-{{> api_box random}}
-
-JavaScript's `Math.random()` returns a pseudorandom number between 0
-(inclusive) and 1 (exclusive). But the language standard doesn't
-guarantee the quality of the random numbers returned. Meteor provides
-`Meteor.random()`, a good PRNG replacement. This function uses the
-[Alea](http://baagoe.org/en/wiki/Better_random_numbers_for_javascript#Alea)
-algorithm to generate random numbers, seeded with the value of `new
-Date()`.
-
- > Meteor.random()
- 0.7759382962249219
-
-{{> api_box uuid}}
-
-`Meteor.uuid()` generates an RFC 4122 version 4 UUID. It is built on
-`Meteor.random()`.
-
- > Meteor.uuid()
- "0ec37060-0d1a-4ddd-b560-d886b891abba"
-
-
+Collections
Meteor stores data in *collections*. To get started, declare a
-collection with `new Meteor.Collection()`.
+collection with `new Meteor.Collection`.
{{> api_box meteor_collection}}
@@ -471,9 +408,8 @@
client and the server, this scratchpad is implemented using Minimongo.)
By default, Meteor automatically publishes every document in your
-collection to each connected client. Any time a client modifies a
-document, and keeps those documents up to date as they change. To turn
-this behavior off, remove the package:
+collection to each connected client. To turn this behavior off, remove
+the package:
$ meteor remove autopublish
@@ -507,10 +443,6 @@
Scratchpad.insert({number: i * 2});
assert(Scratchpad.find({number: {$lt: 9}}).count() === 5);
-Collections provide nearly the same API on both the client and server.
-As a result, in many cases your server methods and client stubs can be
-the same shared code.
-
{{#warning}}
In this preview, Minimongo has some limitations:
@@ -542,42 +474,158 @@
{{> api_box find}}
`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()` to register callbacks when the set of
+return documents. Cursors provide `fetch` to return all matching
+documents, `map` and `forEach` to iterate over all matching
+documents, and `observe` to register callbacks when the set of
matching documents changes.
{{#warning}}
Collection cursors are not query snapshots. If the database changes
-between calling `Collection.find()` and fetching the
+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. This cursor
-behavior mirrors MongoDB itself.
+those changes may or may not appear in the result set.
{{/warning}}
Cursors are a reactive data source. The first time you retrieve a
-cursor's documents with `fetch()`, `map()`, or `forEach()` inside a
+cursor's documents with `fetch`, `map`, or `forEach` inside a
reactive context (eg, [`Meteor.ui.render`](#render),
[`Meteor.autosubscribe`](#autosubscribe), 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()`.
+`find`.
{{> api_box findone}}
-Immediately return a single document without creating an explicit
-cursor. Equivalent to `collection.find(selector, options).fetch()[0]`.
+Equivalent to `find(selector, options).fetch()[0]`.
+
+{{> api_box insert}}
+
+Add a document to the collection. A document is just an object, and
+its fields can contain any combination of JSON-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.
+
+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` returns
+immediately. Once the insert completes (or fails), the callback is
+called with error and result arguments, same as for
+[`methods`](#methods).
+
+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 the error or result of the server's insert.
+
+Example:
+
+ var groceries_id = Lists.insert({name: "Groceries"})._id;
+ Items.insert({list: groceries_id, name: "Watercress"});
+ Items.insert({list: groceries_id, name: "Persimmons"});
+
+{{> api_box update}}
+
+Modify documents that match `selector` as
+given by `modifer` (see modifier
+documentation). By default, modify only one matching document.
+If `multi` is true, modify all matching documents.
+
+Instead of a selector, you can pass a string, which will be
+interpreted as an `_id`.
+
+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 no arguments 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 no arguments if the
+update was successful.
+
+Example:
+
+ // Give the "Superlative" 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.
+ Users.update({score: {$gt: 10}},
+ {badges: {$addToSet: "Superlative"}},
+ {multi: true});
+
+{{#warning}}
+The Mongo `upsert` feature is not implemented.
+{{/warning}}
+
+{{> api_box remove}}
+
+Find all of the documents that match `selector` and delete them from
+the collection. Or instead of a selector, you may pass a string, to
+delete the document with that `_id`. Without any selector, remove all
+documents from the collection.
+
+On the server, if you don't provide a callback, then `remove` blocks
+until the database acknowledges the write, 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 no arguments if the
+update 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 no arguments if the
+update was successful.
+
+Example:
+
+ // Delete all users with a karma of less than -2.
+ Users.remove({karma: {$lt: -2}});
+
+ // Delete all the log entries
+ Logs.remove();
+
+ // Show a list of posts that have been flagged, updating in realtime.
+ // Put a link next to each post that deletes the post if clicked.
+ var frag = Meteor.renderList(Posts, {
+ selector: {flagged: true},
+ render: function (post) {
+ // In real code it'd be necessary to sanitize post.name
+ return $("" + post.name +
+ " Delete
");
+ },
+ events: {
+ 'click .delete': function () {
+ Posts.remove(this._id);
+ }
+ }
+ });
+ document.body.appendChild(frag);
+
+Cursors
+
+To create a cursor, use [`find`](#find). To access the documents in a
+cursor, use [`forEach`](#foreach), [`map`](#map), or [`fetch`](#fetch).
{{> api_box cursor_foreach}}
+
+When called in a reactive context, `forEach` registers dependencies on
+the matching documents.
+
{{> api_box cursor_map}}
+
+When called in a reactive context, `map` registers dependencies on
+the matching documents.
+
{{> api_box cursor_fetch}}
-To access the documents in a cursor, use one of the above
-methods. `forEach` will call a callback function with each
-document in order, `map` returns an array containing the
-results of applying the callback function to each document,
-and `fetch` simply returns an array of the results.
+When called in a reactive context, `fetch` registers dependencies on
+the matching documents.
Examples:
@@ -600,14 +648,15 @@
});
document.body.appendChild(frag);
-When called in a reactive context, `count()` registers a dependency on
-the number of matching documents. (Updates that just change or reorder
-the documents in the result set will *not* trigger a recomputation.)
+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.)
{{> api_box cursor_rewind}}
-To access the data in a cursor more than once, call `rewind` to reset
-the cursor to its initial state.
+The `forEach`, `map`, or `fetch` methods can only be called once on a
+cursor. To access the data in a cursor more than once, use `rewind` to
+reset the cursor.
{{> api_box cursor_observe}}
@@ -617,9 +666,8 @@
`callbacks` may have the following functions as properties:
-
{{#dtdd "added(document, before_index)"}}
-Called when a new document enters the result set. It was inserted
+A new document entered the result set. It was inserted
immediately before the document currently at the
position `before_index`. Or if it was inserted at the end
of the list, `before_index` will be equal to the (prior)
@@ -642,20 +690,16 @@
The document at position `at_index`, which was previously
`old_document`, is no longer in the result set.
{{/dtdd}}
-
`added` will immediately be called as necessary to
deliver the initial results of the query, if any.
-`observe()` returns a live query handle, which is an object with a
-`stop() method. Call this function with no arguments to stop calling
+`observe` returns a live query handle, which is an object with a
+`stop` method. Call this function with no arguments to stop calling
the callback functions and tear down the query. **The query will run
forever until you call this.**
-Calling `observe` in a reactive context does *not* register a dependency
-on the query.
-
Example:
// Keep track of how many administrators are online.
@@ -675,106 +719,6 @@
// After five seconds, stop keeping the count.
setTimeout(function () {handle.stop();}, 5000);
-{{> api_box insert}}
-
-Add a document to the collection. A document is just an object, and
-its fields can contain any combination of JSON-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.
-
-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, the server calls
-that callback with the error and result of the insert command.
-
-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 with
-`Meteor._debug()`. If you provide a callback, Meteor will call that
-function with the error and result of the server's insert.
-
-Example:
-
- var groceries_id = Lists.insert({name: "Groceries"})._id;
- Items.insert({list: groceries_id, name: "Watercress"});
- Items.insert({list: groceries_id, name: "Persimmons"});
-
-{{> api_box update}}
-
-Modify documents that match `selector` as
-given by `modifer` (see modifier
-documentation). By default, modify only one matching document.
-If `multi` is true, modify all matching documents.
-
-Instead of a selector, you can pass a string, which will be
-interpreted as an `_id`.
-
-{{#warning}}
-The Mongo `upsert` feature is not implemented.
-{{/warning}}
-
-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, the server calls
-that callback with the error and result of the update command.
-
-On the client, `update` never blocks. If you do not provide a callback
-and the insert fails on the server, then Meteor will log a warning with
-`Meteor._debug()`. If you provide a callback, Meteor will call that
-function with the error and result of the server's update.
-
-Example:
-
- // Give the "Superlative" 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.
- Users.update({score: {$gt: 10}},
- {badges: {$addToSet: "Superlative"}},
- {multi: true});
-
-{{> api_box remove}}
-
-Find all of the documents that match `selector`, and
-delete them from the collection. Or instead of a selector, you may
-pass a string, to delete the document with that `_id`.
-Without any selector, remove all documents from the collection.
-
-On the server, if you don't provide a callback, then `remove` blocks
-until the database acknowledges the write, or throws an exception if
-something went wrong. If you do provide a callback, the server calls
-that callback with the error and result of the remove command.
-
-On the client, `remove` never blocks. If you do not provide a callback
-and the insert fails on the server, then Meteor will log a warning with
-`Meteor._debug()`. If you provide a callback, Meteor will call that
-function with the error and result of the server's remove.
-
-Example:
-
- // Delete all users with a karma of less than -2.
- Users.remove({karma: {$lt: -2}});
-
- // Delete all the log entries
- Logs.remove();
-
- // Show a list of posts that have been flagged, updating in realtime.
- // Put a link next to each post that deletes the post if clicked.
- var frag = Meteor.renderList(Posts, {
- selector: {flagged: true},
- render: function (post) {
- // In real code it'd be necessary to sanitize post.name
- return $("" + post.name +
- " Delete
");
- },
- events: {
- 'click .delete': function () {
- Posts.remove(this._id);
- }
- }
- });
- document.body.appendChild(frag);
-
{{#api_box_inline selectors}}
In its simplest form, a selector is just a set of keys that must
@@ -867,7 +811,7 @@ Session
// that the chat-history subscription is moved to the room "home".
Session.set("currentRoomId", "home");
-See [`Meteor.deps`](#meteordeps) for another example.
+See [`Meteor.deps`](#meteor_deps) for another example.
{{> api_box get}}
@@ -923,7 +867,7 @@ Session
// the user clicked on an item, the render function would have to
// called once for every Post shown in the list.
-Meteor.ui
+Meteor.ui
These are some utility functions for building interfaces. They make it
easy to create DOM elements that update automatically as data changes in
@@ -946,7 +890,7 @@ Meteor.ui
The auto-updating elements are returned as a `DocumentFragment`. Simply
insert this `DocumentFragment` anywhere in the DOM you like. Its
elements will update themselves automatically until they are taken
-offscreen — specifically, until [`Meteor.flush`](#flush) is called
+offscreen — specifically, until [`Meteor.flush`](#meteor_flush) is called
when the elements are not children of `document`.
`events` lets you quickly hook up some event handlers to
@@ -1003,7 +947,7 @@ Meteor.ui
[`Meteor.ui.render`](#render) — insert it
anywhere, it will automatically update itself, make sure it's on the
page before the next time you
-call [`Meteor.flush`](#flush).
+call [`Meteor.flush`](#meteor_flush).
Example:
@@ -1026,6 +970,37 @@ Meteor.ui
});
document.body.appendChild(frag);
+{{> api_box flush }}
+
+Normally, when you make changes (like writing to the database),
+their impact (like updating the DOM) is delayed until the system is
+idle. This keeps things predictable — you can know that the DOM
+won't go changing out from under your code as it runs. It's also one
+of the things that makes Meteor fast.
+
+`Meteor.flush` forces all of the pending reactive updates to complete
+(for example, it ensures the DOM has been updated with your recent
+database changes.) Call `flush` to apply those pending changes
+immediately. The main use for this is to make sure the DOM has been
+brought up to date with your latest changes, so you can manually
+manipulate it with jQuery or the like.
+
+When you call `flush`, any auto-updating DOM elements that are not on
+the screen may be cleaned up (meaning that Meteor will stop tracking and
+updating the elements, so that the browser's garbage collector can
+delete them.) So, if you manually call `flush`, you need to make sure
+that any auto-updating elements that you have created with templates, or
+by calling [`Meteor.ui.render`](#render), have already been inserted in
+the main DOM tree.
+
+Technically speaking, `flush` calls the [invalidation
+callbacks](#on_invalidate) on every [reactive context](#context) that
+has been [invalidated](#invalidate), but hasn't yet has its callbacks
+called. If the invalidation callbacks invalidate still more contexts,
+flush keeps flushing until everything is totally settled. The DOM
+elements are cleaned up because of logic in
+[`Meteor.ui.render`](#render) that works through invalidations.
+
{{#api_box_inline eventmaps}}
Several functions take event maps. An event map is an object where
@@ -1093,7 +1068,23 @@ Meteor.ui
{{/api_box_inline}}
-Meteor.deps
+Timers
+
+Meteor uses global environment variables
+to keep track of things like the current request's user. To make sure
+these variables have the right values, you need to use
+`Meteor.setTimeout` instead of `setTimeout` and `Meteor.setInterval`
+instead of `setInterval`.
+
+These functions work just like their native JavaScript equivalents.
+You'll get an error if you call the native function.
+
+{{> api_box setTimeout}}
+{{> api_box setInterval}}
+{{> api_box clearTimeout}}
+{{> api_box clearInterval}}
+
+Meteor.deps
Meteor has a simple dependency tracking system, so that it it can
automatically rerender templates and such when [`Session`](#session)
@@ -1135,15 +1126,6 @@ Meteor.deps
invalidation context for your own convenience, as long as they don't
start with an underscore.
-{{> api_box current }}
-
-This is a global variable that is set by [`run`](#run).
-
-If you have a background in Lisp or programming language theory, you
-might think of it as a dynamically scoped ("special") variable. (That
-just means that [`run`](#run) sets it, runs some user-supplied code, and
-then restores its previous value.)
-
{{> api_box run }}
This function simply sets [`Meteor.deps.Context.current`](#current) to
@@ -1207,11 +1189,11 @@ Meteor.deps
the context.
The functions aren't called immediately — instead, they will be
-called the next time you call [`Meteor.flush`](#flush). This function
+called the next time you call [`Meteor.flush`](#meteor_flush). This function
just adds the context to the flush list and is guaranteed to do nothing
else just yet.
-If you don't call [`Meteor.flush`](#flush) explicitly, it will be called
+If you don't call [`Meteor.flush`](#meteor_flush) explicitly, it will be called
for you automatically when your code is done running (by setting a
`setTimeout` timer with a delay of zero.)
@@ -1264,12 +1246,15 @@ Meteor.deps
this.listeners[context_id].invalidate();
};
-Meteor.EnvironmentVariable
+{{> api_box current }}
+
+This is a global variable that is set by [`run`](#run).
+
+If you have a background in Lisp or programming language theory, you
+might think of it as a dynamically scoped ("special") variable. (That
+just means that [`run`](#run) sets it, runs some user-supplied code, and
+then restores its previous value.)
-{{> api_box EnvironmentVariable}}
-{{> api_box environmentVariable_get}}
-{{> api_box environmentVariable_withValue}}
-{{> api_box bindEnvironment}}
{{/better_markdown}}
diff --git a/docs/client/api.js b/docs/client/api.js
index 646e06e95cf..05a21f0a51a 100644
--- a/docs/client/api.js
+++ b/docs/client/api.js
@@ -1,85 +1,19 @@
Template.api.is_client = {
- id: "is_client",
+ id: "meteor_is_client",
name: "Meteor.is_client",
locus: "Anywhere",
descr: ["Boolean variable. True if running in client environment."]
};
Template.api.is_server = {
- id: "is_server",
+ id: "meteor_is_server",
name: "Meteor.is_server",
locus: "Anywhere",
descr: ["Boolean variable. True if running in server environment."]
};
-Template.api.setTimeout = {
- id: "settimeout",
- name: "Meteor.setTimeout",
- locus: "Anywhere",
- descr: ["Call a function in the future after waiting for a specified delay."],
- args: [
- {
- name: "func",
- type: "Function",
- descr: "The function to run"
- },
- {
- name: "delay",
- type: "Number",
- descr: "Number of milliseconds to wait before calling function"
- }
- ]
-};
-
-Template.api.setInterval = {
- id: "setinterval",
- name: "Meteor.setInterval",
- locus: "Anywhere",
- descr: ["Call a function repeatedly, with a time delay between calls."],
- args: [
- {
- name: "func",
- type: "Function",
- descr: "The function to run"
- },
- {
- name: "delay",
- type: "Number",
- descr: "Number of milliseconds to wait between each function call."
- }
- ]
-};
-
-Template.api.clearTimeout = {
- id: "cleartimeout",
- name: "Meteor.clearTimeout",
- locus: "Anywhere",
- descr: ["Cancel a function call scheduled by `Meteor.setTimeout`."],
- args: [
- {
- name: "id",
- type: "Number",
- descr: "The handle returned from setTimeout"
- }
- ]
-};
-
-Template.api.clearInterval = {
- id: "clearinterval",
- name: "Meteor.clearInterval",
- locus: "Anywhere",
- descr: ["Cancel a repeating function call scheduled by `Meteor.setInterval`."],
- args: [
- {
- name: "id",
- type: "Number",
- descr: "The handle returned from setInterval"
- }
- ]
-};
-
Template.api.startup = {
- id: "startup",
+ id: "meteor_startup",
name: "Meteor.startup(func)",
locus: "Anywhere",
descr: ["Run code when a client or a server starts."],
@@ -91,112 +25,112 @@ Template.api.startup = {
};
Template.api.publish = {
- id: "publish",
+ id: "meteor_publish",
name: "Meteor.publish(name, func)",
locus: "Server",
- descr: ["Publish an attribute set."],
+ descr: ["Publish a record set."],
args: [
{name: "name",
type: "String",
- descr: "Name of the attribute set. If `null`, the set has no name, and every connected client is automatically subscribed."},
+ descr: "Name of the attribute set. If `null`, the set has no name, and the record set is automatically sent to all connected clients."},
{name: "func",
type: "Function",
descr: "Function called on the server each time a client subscribes. Inside function, `this` is the publish handler object, described below. If the client passed arguments to `subscribe`, the function is called with the same arguments."}
]
};
-Template.api.subscription_stop = {
- id: "subscriptionstop",
- name: "this.stop()",
- locus: "Server",
- descr: ["Call inside publish function. Stops this client's subscription."]
-};
-
-Template.api.subscription_onStop = {
- id: "subscriptiononstop",
- name: "this.onStop(func)",
- locus: "Server",
- descr: ["Call inside publish function. Registers a callback function to run when the subscription is stopped."],
- args: [
- {name: "func",
- type: "Function",
- descr: "The callback function"
- }
- ]
-};
-
Template.api.subscription_set = {
- id: "subscriptionset",
+ id: "publish_set",
name: "this.set(collection, id, name, value)",
locus: "Server",
descr: ["Call inside publish function. Queues a command to set an attribute value."],
args: [
{name: "collection",
type: "String",
- descr: "The name of the attribute's collection"
+ descr: "The name of the collection that should be affected."
},
{name: "id",
type: "String",
- descr: "The id of the attribute's document"
+ descr: "The ID of the document that should be affected."
},
{name: "name",
type: "String",
- descr: "The name of the attribute"
+ descr: "The name of the attribute."
},
{name: "value",
type: "JSON",
- descr: "The new value of the attribute"
+ descr: "The new value of the attribute."
}
]
};
Template.api.subscription_unset = {
- id: "subscriptionunset",
+ id: "publish_unset",
name: "this.unset(collection, id, name)",
locus: "Server",
descr: ["Call inside publish function. Queues a command to unset an attribute."],
args: [
{name: "collection",
type: "String",
- descr: "The name of the attribute's collection"
+ descr: "The name of the collection that should be affected."
},
{name: "id",
type: "String",
- descr: "The id of the attribute's document"
+ descr: "The ID of the document that should be affected."
},
{name: "name",
type: "String",
- descr: "The name of the attribute"
+ descr: "The name of the attribute."
}
]
};
Template.api.subscription_complete = {
- id: "subscriptioncomplete",
+ id: "publish_complete",
name: "this.complete()",
locus: "Server",
descr: ["Call inside publish function. Queues a command to mark this subscription as complete (inital attributes are set)."]
};
Template.api.subscription_flush = {
- id: "subscriptionflush",
+ id: "publish_flush",
name: "this.flush()",
locus: "Server",
- descr: ["Call inside publish function. Coalesce and send and pending set, unset, and complete messages to the client."]
+ descr: ["Call inside publish function. Sends all the pending set, unset, and complete messages to the client."]
+};
+
+Template.api.subscription_stop = {
+ id: "publish_stop",
+ name: "this.stop()",
+ locus: "Server",
+ descr: ["Call inside publish function. Stops this client's subscription."]
+};
+
+Template.api.subscription_onStop = {
+ id: "publish_onstop",
+ name: "this.onStop(func)",
+ locus: "Server",
+ descr: ["Call inside publish function. Registers a callback function to run when the subscription is stopped."],
+ args: [
+ {name: "func",
+ type: "Function",
+ descr: "The callback function"
+ }
+ ]
};
Template.api.subscribe = {
- id: "subscribe",
+ id: "meteor_subscribe",
name: "Meteor.subscribe(name [, arg1, arg2, ... ] [, onComplete])",
locus: "Client",
- descr: ["Subscribe to a set of attributes. Returns a handle that provides a stop() method, which will unsubscribe the client from this attribute set."],
+ descr: ["Subscribe to a record set. Returns a handle that provides a stop() method, which will stop the subscription."],
args: [
{name: "name",
type: "String",
- descr: "Name of the subscription, matches name of server's publish() call."},
+ descr: "Name of the subscription. Matches name of server's publish() call."},
{name: "arg1, arg2, ...",
type: "Any",
- descr: "Optional arguments, passed to publisher function on server."},
+ descr: "Optional arguments passed to publisher function on server."},
{name: "onComplete",
type: "Function",
descr: "If the last argument is a Function, it is called without arguments when the server marks the subscription as complete."}
@@ -204,7 +138,7 @@ Template.api.subscribe = {
};
Template.api.autosubscribe = {
- id: "autosubscribe",
+ id: "meteor_autosubscribe",
name: "Meteor.autosubscribe(func)",
locus: "Client",
descr: ["Automatically set up and tear down subscriptions."],
@@ -216,79 +150,40 @@ Template.api.autosubscribe = {
};
Template.api.methods = {
- id: "methods",
+ id: "meteor_methods",
name: "Meteor.methods(methods)",
locus: "Anywhere",
- descr: ["Defines methods and stubs."],
+ descr: ["Defines functions that can be invoked over the network by clients."],
args: [
{name: "methods",
- type: Object,
- descr: "Dictionary whose keys are method names and values are JavaScript functions."}
- ]
-};
-
-Template.api.call = {
- id: "call",
- name: "Meteor.call(func, arg1, arg2, ... [, asyncCallback])",
- locus: "Anywhere",
- descr: ["Invokes a method using call() style."],
- args: [
- {name: "func",
- type: "String",
- descr: "Name of method to invoke"},
- {name: "arg1, arg2, ...",
- type: "JSON",
- descr: "Optional method arguments"},
- {name: "asyncCallback",
- type: "Function",
- descr: "Optional callback. If passed, the method runs asynchronously, and calls the callback with error and result arguments."}
- ]
-};
-
-Template.api.apply = {
- id: "apply",
- name: "Meteor.apply(name, params [, asyncCallback])",
- locus: "Anywhere",
- descr: ["Invoke a method using apply() style."],
- args: [
- {name: "name",
- type: "String",
- descr: "Name of method to invoke"},
- {name: "params",
- type: "Array",
- descr: "Method arguments"},
- {name: "asyncCallback",
- type: "Function",
- descr: "Optional callback. If passed, the method runs asynchronously, and calls the callback with error and result arguments."}
+ type: "Object",
+ descr: "Dictionary whose keys are method names and values are functions."}
]
};
-// onAutopublish
-// onQuiesce
-
Template.api.method_invocation_unblock = {
- id: "invocationunblock",
+ id: "method_unblock",
name: "this.unblock()",
locus: "Server",
descr: ["Call inside method invocation. Allow subsequent method from this client to begin running in a new fiber."]
};
Template.api.method_invocation_is_simulation = {
- id: "invocationis_simulation",
+ id: "method_is_simulation",
name: "this.is_simulation",
locus: "Anywhere",
descr: ["Access inside method invocation. Boolean value, true if this invocation is a stub."]
};
Template.api.error = {
- id: "error",
- name: "Meteor.Error(error, reason, details)",
+ id: "meteor_error",
+ name: "new Meteor.Error(error, reason, details)",
locus: "Anywhere",
- descr: ["Constructor for a Meteor Error object."],
+ descr: ["This class represents a symbolic error thrown by a method."],
args: [
{name: "error",
type: "Number",
- descr: "A numeric error code, likely similar to a HTTP code (eg, 404, 500). This is likely to change."},
+ descr: "A numeric error code, likely similar to a HTTP code (eg, 404, 500)."},
{name: "reason",
type: "String",
descr: "Optional. A short human-readable summary of the error, like 'Not Found'."},
@@ -298,205 +193,76 @@ Template.api.error = {
]
};
-// xxx
-
-Template.api.Context = {
- id: "context",
- name: "new Meteor.deps.Context",
- locus: "Client",
- descr: ["Create an invalidation context. Invalidation contexts are used to run a piece of code, and record its dependencies so it can be rerun later if one of its inputs changes.", "An invalidation context is basically just a list of callbacks for an event that can fire only once. The `on_invalidate|on_invalidate` method adds a callback to the list, and the `invalidate|invalidate` method fires the event."]
-};
-
-Template.api.current = {
- id: "current",
- name: "Meteor.deps.Context.current",
- locus: "Client",
- descr: ["The current `invalidation context|context`, or `null` if not being called from inside `run|run`."]
-};
-
-Template.api.run = {
- id: "run",
- name: "context.run(func)",
- locus: "Client",
- descr: ["Run some code inside an evaluation context."],
+Template.api.call = {
+ id: "meteor_call",
+ name: "Meteor.call(func, arg1, arg2, ... [, asyncCallback])",
+ locus: "Anywhere",
+ descr: ["Invokes a method passing any number of arguments."],
args: [
{name: "func",
- type: "Function",
- descr: "The code to run"}
- ]
-};
-
-Template.api.on_invalidate = {
- id: "on_invalidate",
- name: "context.on_invalidate(callback)",
- locus: "Client",
- descr: ["Registers `callback` to be called when this context is invalidated. `callback` will be run exactly once."],
- args: [
- {name: "callback",
- type: "Function",
- descr: "Function to be called on invalidation. Receives one argument, the context that was invalidated"}
- ]
-};
-
-Template.api.invalidate = {
- id: "invalidate",
- name: "context.invalidate()",
- locus: "Client",
- descr: ["Add this context to the list of contexts that will have their `on_invalidate|on_invalidate` callbacks called by the next call to [`Meteor.flush`](#flush)."]
-};
-
-Template.api.flush = {
- id: "flush",
- name: "Meteor.flush()",
- locus: "Client",
- descr: ["Ensure than any reactive updates have finished. Allow auto-updating DOM element to be cleaned up if they are offscreen."]
-};
-
-Template.api.connect = {
- id: "connect",
- name: "Meteor.connect(url)",
- locus: "Client",
- descr: ["Connect to a DDP server at the provided URL."],
- args: [
- {name: "url",
type: "String",
- descr: "The URL of a DDP endpoint."}
- ]
-};
-
-Template.api.status = {
- id: "status",
- name: "Meteor.status()",
- locus: "Client",
- descr: ["Get the current connection status. A reactive data source."]
-};
-
-Template.api.reconnect = {
- id: "reconnect",
- name: "Meteor.reconnect()",
- locus: "Client",
- descr: [
- "Force an immediate reconnection attempt if the client is not connected to the server",
- "If the client is already connected this method does nothing."]
-};
-
-
-// writeFence
-// invalidationCrossbar
-
-Template.api.render = {
- id: "render",
- name: "Meteor.ui.render(render_func, [events], [event_data])",
- locus: "Client",
- descr: ["Create reactive DOM elements that automatically update themselves as data changes in the database or session variables."],
- args: [
- {name: "render_func",
- type: "Function returning a DOM element, an array of DOM elements, a DocumentFragment, a jQuery-style result set, or a string",
- descr: "Function that renders the DOM elements"},
- {name: "events",
- type: "Object — event map",
- type_link: "eventmaps",
- descr: "Events to hook up to the rendered elements"},
- {name: "event_data",
- type: "Any value",
- descr: "Value to bind to `this` in event handlers"
- }
- ]
-};
-
-Template.api.renderList = {
- id: "renderlist",
- name: "Meteor.ui.renderList(collection, options)",
- locus: "Client",
- descr: ["Do a database query and repeat a template for each result. Keep the query running constantly, and return reactive DOM elements that automatically update themselves as the results of the query change."],
- args: [
- {name: "collection",
- type: "Collection",
- type_link: "collection",
- descr: "The collection to query"}],
- options: [
- {name: "render",
- type: "Function (required)", // XXX document that it's reactive
- descr: "Takes a document from the collection and returns a DOM element"},
- {name: "render_empty",
+ descr: "Name of method to invoke"},
+ {name: "arg1, arg2, ...",
+ type: "JSON",
+ descr: "Optional method arguments"},
+ {name: "asyncCallback",
type: "Function",
- descr: "Return something to show when the query has no results"},
- {name: "selector",
- type: "Object — Mongo selector",
- type_link: "selectors",
- descr: "Filter (default: `{}`, all records)"},
- {name: "sort",
- type: "Object — sort specifier",
- type_link: "sortspecifiers",
- descr: "Ordering (default: natural order in the database)"},
- {name: "events",
- type: "Object — event map",
- type_link: "eventmaps",
- descr: "Events to hook up to each rendered element"}
+ descr: "Optional callback. If passed, the method runs asynchronously, instead of synchronously, and calls asyncCallback passing either the error or the result."}
]
};
-Template.api.eventmaps = {
- id: "eventmaps",
- name: "Event Maps"
-};
-
-Template.api.EnvironmentVariable = {
- id: "meteorenvironmentvariable",
- name: "new Meteor.EnvironmentVariable()",
- locus: "Anywhere",
- descr: ["Construct a Meteor environment variable."]
-};
-
-Template.api.environmentVariable_get = {
- id: "environment_variableget",
- name: "env_var.get()",
- locus: "Anywhere",
- descr: ["Return the current value of an EnvironmentVariable."]
-};
-
-Template.api.environmentVariable_withValue = {
- id: "environment_variablewithvalue",
- name: "env_var.withValue(value, func)",
+Template.api.apply = {
+ id: "meteor_apply",
+ name: "Meteor.apply(name, params [, asyncCallback])",
locus: "Anywhere",
- descr: ["Run `func` with the `env_var`'s value set to `value`."],
+ descr: ["Invoke a method passing an array of arguments."],
args: [
- {name: "valuen",
- type: "Anything",
- descr: "Desired value of the environment variable."},
- {name: "func",
+ {name: "name",
+ type: "String",
+ descr: "Name of method to invoke"},
+ {name: "params",
+ type: "Array",
+ descr: "Method arguments"},
+ {name: "asyncCallback",
type: "Function",
- descr: "Function to call"}
+ descr: "Optional callback. If passed, the method runs asynchronously, instead of synchronously, and calls asyncCallback passing either the error or the result."}
]
};
-Template.api.bindEnvironment = {
- id: "environment_variablebindenvironment",
- name: "env_var.bindEnvironment(func, onException, _this)",
- locus: "Anywhere",
- descr: ["Return a new function that calls `func` with `this` set to `_this`, and with environment variables set to their current values."],
+Template.api.status = {
+ id: "meteor_status",
+ name: "Meteor.status()",
+ locus: "Client",
+ descr: ["Get the current connection status. A reactive data source."]
+};
+
+Template.api.reconnect = {
+ id: "meteor_reconnect",
+ name: "Meteor.reconnect()",
+ locus: "Client",
+ descr: [
+ "Force an immediate reconnection attempt if the client is not connected to the server.",
+ "This method does nothing if the client is already connected."]
+};
+
+Template.api.connect = {
+ id: "meteor_connect",
+ name: "Meteor.connect(url)",
+ locus: "Client",
+ descr: ["Connect to the server of a different Meteor application to subscribe to its document sets and invoke its remote methods."],
args: [
- {name: "func",
- type: "Function",
- descr: "Function to wrap"},
- {name: "onException",
- type: "Function",
- descr: "Function to call if `func` throws an exception. It expects the thrown exception as its single argument."},
- {name: "_this",
- type: "Object",
- descr: "Value of `this` inside `func`."}
+ {name: "url",
+ type: "String",
+ descr: "The URL of another Meteor application."}
]
};
-Template.api.local_collection = {
- id: "local_collection",
- name: "new LocalCollection()",
- locus: "Anywhere",
- descr: ["Create a MongoDB-style collection that can be used to store data."]
-};
+// onAutopublish
+// onQuiesce
+
Template.api.meteor_collection = {
- id: "meteorcollection",
- name: "Meteor.Collection(name, manager)", // driver undocumented
+ id: "meteor_collection",
+ name: "new Meteor.Collection(name, manager)", // driver undocumented
locus: "Anywhere",
descr: ["Constructor for a Collection"],
args: [
@@ -511,12 +277,11 @@ Template.api.meteor_collection = {
]
};
-
Template.api.find = {
id: "find",
name: "collection.find(selector, [options])",
locus: "Anywhere",
- descr: ["Defines a query of documents in a collection that match a selector. Does not execute the query."],
+ descr: ["Find the documents in a collection that match the selector."],
args: [
{name: "selector",
type: "Object — Mongo selector, or String",
@@ -544,7 +309,7 @@ Template.api.findone = {
id: "findone",
name: "collection.findOne(selector, [options])",
locus: "Anywhere",
- descr: ["Returns the first document matching selector, as ordered by sort and skip options."],
+ descr: ["Finds the first document that matches the selector, as ordered by sort and skip options."],
args: [
{name: "selector",
type: "Object — Mongo selector, or String",
@@ -566,47 +331,45 @@ Template.api.findone = {
};
Template.api.cursor_count = {
- id: "cursorcount",
+ id: "count",
name: "cursor.count()",
locus: "Anywhere",
- descr: ["Returns the count of documents matched by a query."],
- args: [ ],
+ descr: ["Returns the number of documents that match a query."]
};
Template.api.cursor_fetch = {
- id: "cursorfetch",
+ id: "fetch",
name: "cursor.fetch()",
locus: "Anywhere",
- descr: ["Returns the array of documents matching the query."],
- args: [ ]
+ descr: ["Return all matching documents as an Array."]
};
Template.api.cursor_foreach = {
- id: "cursorforeach",
+ id: "foreach",
name: "cursor.forEach(callback)",
locus: "Anywhere",
- descr: ["Iterates over all matching documents."],
+ descr: ["Call the callback function once for each matching document."],
args: [
{name: "callback",
type: "Function",
- descr: "Function to call, supplying each matching document as its single argument."}
+ descr: "Function to call."}
]
};
Template.api.cursor_map = {
- id: "cursormap",
+ id: "map",
name: "cursor.map(callback)",
locus: "Anywhere",
- descr: ["Map over all matching documents, returning Array."],
+ descr: ["Map callback over all matching documents. Returns an Array."],
args: [
{name: "callback",
type: "Function",
- descr: "Function to call, supplying each matching document as its single argument."}
+ descr: "Function to call."}
]
};
Template.api.cursor_rewind = {
- id: "cursorrewind",
+ id: "rewind",
name: "cursor.rewind()",
locus: "Anywhere",
descr: ["Resets the query cursor."],
@@ -614,10 +377,10 @@ Template.api.cursor_rewind = {
};
Template.api.cursor_observe = {
- id: "cursorobserve",
+ id: "observe",
name: "cursor.observe(options)",
locus: "Client",
- descr: ["Continuously query a collection for documents that match a selector. Receive callbacks as the result set changes."],
+ descr: ["Watch a query. Receive callbacks as the result set changes."],
args: [
{name: "callbacks",
type: "Object (may include added, changed, moved, removed callbacks)",
@@ -696,9 +459,234 @@ Template.api.sortspecifiers = {
name: "Sort Specifiers"
};
+Template.api.Context = {
+ id: "context",
+ name: "new Meteor.deps.Context",
+ locus: "Client",
+ descr: ["Create an invalidation context. Invalidation contexts are used to run a piece of code, and record its dependencies so it can be rerun later if one of its inputs changes.", "An invalidation context is basically just a list of callbacks for an event that can fire only once. The [`on_invalidate`](#on_invalidate) method adds a callback to the list, and the [`invalidate`](#invalidate) method fires the event."]
+};
+
+Template.api.current = {
+ id: "current",
+ name: "Meteor.deps.Context.current",
+ locus: "Client",
+ descr: ["The current [`invalidation context`](#context), or `null` if not being called from inside [`run`](#run)."]
+};
+
+Template.api.run = {
+ id: "run",
+ name: "context.run(func)",
+ locus: "Client",
+ descr: ["Run some code inside an evaluation context."],
+ args: [
+ {name: "func",
+ type: "Function",
+ descr: "The code to run"}
+ ]
+};
+
+Template.api.on_invalidate = {
+ id: "on_invalidate",
+ name: "context.on_invalidate(callback)",
+ locus: "Client",
+ descr: ["Registers `callback` to be called when this context is invalidated. `callback` will be run exactly once."],
+ args: [
+ {name: "callback",
+ type: "Function",
+ descr: "Function to be called on invalidation. Receives one argument, the context that was invalidated"}
+ ]
+};
+
+Template.api.invalidate = {
+ id: "invalidate",
+ name: "context.invalidate()",
+ locus: "Client",
+ descr: ["Add this context to the list of contexts that will have their `on_invalidate|on_invalidate` callbacks called by the next call to [`Meteor.flush`](#flush)."]
+};
+
+
+// writeFence
+// invalidationCrossbar
+
+Template.api.render = {
+ id: "meteor_ui_render",
+ name: "Meteor.ui.render(render_func, [events], [event_data])",
+ locus: "Client",
+ descr: ["Create reactive DOM elements that automatically update themselves as data changes in the database or session variables."],
+ args: [
+ {name: "render_func",
+ type: "Function returning a DOM element, an array of DOM elements, a DocumentFragment, a jQuery-style result set, or a string",
+ descr: "Function that renders the DOM elements"},
+ {name: "events",
+ type: "Object — event map",
+ type_link: "eventmaps",
+ descr: "Events to hook up to the rendered elements"},
+ {name: "event_data",
+ type: "Any value",
+ descr: "Value to bind to `this` in event handlers"
+ }
+ ]
+};
+
+Template.api.renderList = {
+ id: "meteor_ui_renderlist",
+ name: "Meteor.ui.renderList(collection, options)",
+ locus: "Client",
+ descr: ["Do a database query and repeat a template for each result. Keep the query running constantly, and return reactive DOM elements that automatically update themselves as the results of the query change."],
+ args: [
+ {name: "collection",
+ type: "Collection",
+ type_link: "collection",
+ descr: "The collection to query"}],
+ options: [
+ {name: "render",
+ type: "Function (required)", // XXX document that it's reactive
+ descr: "Takes a document from the collection and returns a DOM element"},
+ {name: "render_empty",
+ type: "Function",
+ descr: "Return something to show when the query has no results"},
+ {name: "selector",
+ type: "Object — Mongo selector",
+ type_link: "selectors",
+ descr: "Filter (default: `{}`, all records)"},
+ {name: "sort",
+ type: "Object — sort specifier",
+ type_link: "sortspecifiers",
+ descr: "Ordering (default: natural order in the database)"},
+ {name: "events",
+ type: "Object — event map",
+ type_link: "eventmaps",
+ descr: "Events to hook up to each rendered element"}
+ ]
+};
+
+Template.api.flush = {
+ id: "meteor_flush",
+ name: "Meteor.flush()",
+ locus: "Client",
+ descr: ["Ensure than any reactive updates have finished. Allow auto-updating DOM element to be cleaned up if they are offscreen."]
+};
+
+Template.api.eventmaps = {
+ id: "eventmaps",
+ name: "Event Maps"
+};
+
+Template.api.setTimeout = {
+ id: "meteor_settimeout",
+ name: "Meteor.setTimeout",
+ locus: "Anywhere",
+ descr: ["Call a function in the future after waiting for a specified delay."],
+ args: [
+ {
+ name: "func",
+ type: "Function",
+ descr: "The function to run"
+ },
+ {
+ name: "delay",
+ type: "Number",
+ descr: "Number of milliseconds to wait before calling function"
+ }
+ ]
+};
+
+Template.api.setInterval = {
+ id: "meteor_setinterval",
+ name: "Meteor.setInterval",
+ locus: "Anywhere",
+ descr: ["Call a function repeatedly, with a time delay between calls."],
+ args: [
+ {
+ name: "func",
+ type: "Function",
+ descr: "The function to run"
+ },
+ {
+ name: "delay",
+ type: "Number",
+ descr: "Number of milliseconds to wait between each function call."
+ }
+ ]
+};
+
+Template.api.clearTimeout = {
+ id: "meteor_cleartimeout",
+ name: "Meteor.clearTimeout",
+ locus: "Anywhere",
+ descr: ["Cancel a function call scheduled by `Meteor.setTimeout`."],
+ args: [
+ {
+ name: "id",
+ type: "Number",
+ descr: "The handle returned from setTimeout"
+ }
+ ]
+};
+
+Template.api.clearInterval = {
+ id: "meteor_clearinterval",
+ name: "Meteor.clearInterval",
+ locus: "Anywhere",
+ descr: ["Cancel a repeating function call scheduled by `Meteor.setInterval`."],
+ args: [
+ {
+ name: "id",
+ type: "Number",
+ descr: "The handle returned from setInterval"
+ }
+ ]
+};
+
+Template.api.EnvironmentVariable = {
+ id: "meteor_environmentvariable",
+ name: "new Meteor.EnvironmentVariable()",
+ locus: "Anywhere",
+ descr: ["Construct a Meteor environment variable."]
+};
+
+Template.api.environmentVariable_get = {
+ id: "env_var_get",
+ name: "env_var.get()",
+ locus: "Anywhere",
+ descr: ["Return the current value of an EnvironmentVariable."]
+};
+
+Template.api.environmentVariable_withValue = {
+ id: "env_var_withvalue",
+ name: "env_var.withValue(value, func)",
+ locus: "Anywhere",
+ descr: ["Run `func` with the `env_var`'s value set to `value`."],
+ args: [
+ {name: "value",
+ type: "Anything",
+ descr: "Desired value of the environment variable."},
+ {name: "func",
+ type: "Function",
+ descr: "Function to call"}
+ ]
+};
+
+Template.api.bindEnvironment = {
+ id: "env_var_bindenvironment",
+ name: "env_var.bindEnvironment(func, onException, _this)",
+ locus: "Anywhere",
+ descr: ["Return a new function that calls `func` with `this` set to `_this`, and with environment variables set to their current values."],
+ args: [
+ {name: "func",
+ type: "Function",
+ descr: "Function to wrap"},
+ {name: "onException",
+ type: "Function",
+ descr: "Function to call if `func` throws an exception. It expects the thrown exception as its single argument."},
+ {name: "_this",
+ type: "Object",
+ descr: "Value of `this` inside `func`."}
+ ]
+};
Template.api.set = {
- id: "set",
+ id: "session_set",
name: "Session.set(key, value)",
locus: "Client",
descr: ["Set a variable in the session. Notify any listeners that the value has changed (eg: redraw templates, and rerun any [`Meteor.autosubscribe`](#autosubscribe) blocks, that called [`Session.get`](#get) on this `key`.)"],
@@ -713,7 +701,7 @@ Template.api.set = {
};
Template.api.get = {
- id: "get",
+ id: "session_get",
name: "Session.get(key)",
locus: "Client",
descr: ["Get the value of a session variable. If inside a [`Meteor.monitor`](#monitor) block, invalidate the block the next time the value of the variable is changed by [`Session.set`](#set)."],
@@ -725,7 +713,7 @@ Template.api.get = {
};
Template.api.equals = {
- id: "equals",
+ id: "session_equals",
name: "Session.equals(key, value)",
locus: "Client",
descr: ["Test if a session variable is equal to a value. If inside a [`Meteor.monitor`](#monitor) block, invalidate the block the next time the variable changes to or from the value."],
@@ -738,17 +726,3 @@ Template.api.equals = {
descr: "The value to test against"}
]
};
-
-Template.api.uuid = {
- id: "uuid",
- name: "Meteor.uuid()",
- locus: "Anywhere",
- descr: ["Generate an RFC 4122 v4 UUID."]
-};
-
-Template.api.random = {
- id: "random",
- name: "Meteor.random()",
- locus: "Anywhere",
- descr: ["Generate a random Number between 0 and 1."]
-};
diff --git a/docs/client/concepts.html b/docs/client/concepts.html
index e10b1b9ff54..3cc71c97232 100644
--- a/docs/client/concepts.html
+++ b/docs/client/concepts.html
@@ -227,7 +227,7 @@ Templates
To render the template, you simply call the function:
-
+
<!-- in myapp.html -->
<template name="hello">
<div class="greeting">Hello there, {{first}} {{last}}!</div>
@@ -235,9 +235,7 @@ Templates
// in the JavaScript console
> Template.hello({first: "Alyssa", last: "Hacker"});
- => <div class="greeting">Hello there, Alyssa Hacker!</div>
-
-
+ => <div class="greeting">Hello there, Alyssa Hacker!</div>
In addition to passing JSON data directly to the template function,
you can also provide data to templates by setting additional
@@ -256,8 +254,7 @@ Templates
{{#each top_10_scorers}}
<div>{{name}}</div>
{{/each}}
-</template>
-
+</template>
Functions can take arguments, and they receive the current template
data in this
.
@@ -277,8 +274,7 @@ Templates
<div>Senior: {{name}}</div>
{{/if}}
{{/each}}
-</template>
-
+</template>
Handlebars note:
{{#if league_is "junior"}}
is
@@ -292,8 +288,7 @@
Templates
// Works fine with {{#each sections}}
-Template.report.sections = ["Situation", "Complication", "Resolution"];
-
+Template.report.sections = ["Situation", "Complication", "Resolution"];
Finally, you can set the
events
property of a template
function to a table of event handlers. The format is documented at
@@ -326,8 +321,7 @@
Templates
'click .give_points': function () {
Users.update({_id: this._id}, {$inc: {score: 2}});
}
-};
-
+};
Templates are reactive — they are automatically wrapped
in
Meteor.ui.render
. So, the DOM
@@ -353,8 +347,7 @@
Templates
> document.body.appendChild(x);
> Session.set("weather", "cool and dry");
> x
- => <div>It'll be cool and dry tonight</div>
-
+ => <div>It'll be cool and dry tonight</div>
The auto-updating continues as long as the elements are on the
screen. The specific rule is: if the elements are not children
diff --git a/docs/client/docs.css b/docs/client/docs.css
index 92c76d0779b..aa6867084ab 100644
--- a/docs/client/docs.css
+++ b/docs/client/docs.css
@@ -151,6 +151,15 @@ em {
letter-spacing: 0px;
}
+#nav h4 {
+ font-size: .8em;
+ font-weight: normal;
+ margin: 4px 0px 4px 0px;
+ padding-left: 20px;
+ color: #333333;
+ letter-spacing: 0px;
+}
+
#nav .spacer {
height: .33em;
}
diff --git a/docs/client/docs.html b/docs/client/docs.html
index dabca552df9..31b3e112ece 100644
--- a/docs/client/docs.html
+++ b/docs/client/docs.html
@@ -5,6 +5,7 @@
+
{{> introduction }}
{{> examples }}
{{> concepts }}
@@ -21,13 +22,14 @@
diff --git a/docs/client/docs.js b/docs/client/docs.js
index c6e4a6d4413..46186b480b4 100644
--- a/docs/client/docs.js
+++ b/docs/client/docs.js
@@ -1,3 +1,5 @@
+METEOR_VERSION = "0.1.5";
+
Meteor.startup(function () {
var layout = $('body').layout({west: {size: 300}});
// XXX this is broken by the new multi-page layout. Also, it was
@@ -46,7 +48,7 @@ Meteor.startup(function () {
});
var toc = [
- "Introduction", [
+ {name: "Meteor " + METEOR_VERSION, id: "top"}, [
"Quick start",
"Seven principles",
"Resources"
@@ -65,55 +67,58 @@ var toc = [
],
"API", [
- "Meteor", [
- "is_client",
- "is_server",
- "startup",
- "setTimeout",
- "setInterval",
- "clearTimeout",
- "clearInterval",
-
- "publish",
- "subscription.set",
- "subscription.unset",
- "subscription.complete",
- "subscription.flush",
- "subscription.onStop",
- "subscription.stop",
- "subscribe",
- "autosubscribe",
-
- "methods",
- "Error",
- "invocation.is_simulation",
- "invocation.unblock",
- "call",
- "apply",
-
- "status",
- "reconnect",
- "connect",
-
- "flush",
-
- "random",
- "uuid"
+ "Core", [
+ "Meteor.is_client",
+ "Meteor.is_server",
+ "Meteor.startup"
+ ],
+
+ "Publish and subscribe", [
+ "Meteor.publish", [
+ {instance: "this", name: "set", id: "publish_set"},
+ {instance: "this", name: "unset", id: "publish_unset"},
+ {instance: "this", name: "complete", id: "publish_complete"},
+ {instance: "this", name: "flush", id: "publish_flush"},
+ {instance: "this", name: "onStop", id: "publish_onstop"},
+ {instance: "this", name: "stop", id: "publish_stop"}
+ ],
+ "Meteor.subscribe",
+ "Meteor.autosubscribe"
+ ],
+
+ {name: "Methods", id: "methods_header"}, [
+ "Meteor.methods", [
+ {instance: "this", name: "is_simulation", id: "method_is_simulation"},
+ {instance: "this", name: "unblock", id: "method_unblock"}
+ ],
+ "Meteor.Error",
+ "Meteor.call",
+ "Meteor.apply"
],
- {name: "Meteor.Collection", id: "meteorcollection_header"}, [
- "Meteor.Collection",
- "find",
- "findOne",
- "cursor.foreach",
- "cursor.map",
- "cursor.fetch",
- "cursor.count",
- "cursor.rewind",
- "cursor.observe",
- "insert",
- "update",
- "remove",
+ {name: "Server connections", id: "connections"}, [
+ "Meteor.status",
+ "Meteor.reconnect",
+ "Meteor.connect"
+ ],
+
+ {name: "Collections", id: "collections"}, [
+ "Meteor.Collection", [
+ {instance: "collection", name: "find"},
+ {instance: "collection", name: "findOne"},
+ {instance: "collection", name: "insert"},
+ {instance: "collection", name: "update"},
+ {instance: "collection", name: "remove"}
+ ],
+
+ "Meteor.Collection.Cursor", [
+ {instance: "cursor", name: "forEach"},
+ {instance: "cursor", name: "map"},
+ {instance: "cursor", name: "fetch"},
+ {instance: "cursor", name: "count"},
+ {instance: "cursor", name: "rewind"},
+ {instance: "cursor", name: "observe"}
+ ],
{type: "spacer"},
{name: "Selectors", style: "noncode"},
{name: "Modifiers", style: "noncode"},
@@ -121,66 +126,72 @@ var toc = [
],
"Session", [
- "set",
- "get",
- "equals"
+ "Session.set",
+ "Session.get",
+ "Session.equals"
],
"Meteor.ui", [
- "render",
- "renderList",
+ "Meteor.ui.render",
+ "Meteor.ui.renderList",
+ "Meteor.flush",
{type: "spacer"},
{name: "Event maps", style: "noncode"}
],
- {type: "spacer"},
-
- "Meteor.deps", [
- {name: "Meteor.deps.Context", id: "context"},
- {name: "Meteor.deps.Context.current", id: "current"},
- "run",
- {name: "on_invalidate", id: "on_invalidate"},
- "invalidate"
+ "Timers", [
+ "Meteor.setTimeout",
+ "Meteor.setInterval",
+ "Meteor.clearTimeout",
+ "Meteor.clearInterval"
],
- {name: "Meteor.EnvironmentVariable", id: "meteor_environmentvariable"}, [
- "Meteor.EnvironmentVariable",
- "environment_variable.get",
- "environment_variable.withValue",
- "environment_variable.bindEnvironment"
- ],
-
- // "EnvironmentVariable",
-
- "Packages", [
- "amplify",
- "backbone",
- "coffeescript",
- "jquery",
- "less",
- "showdown",
- "underscore"
- ],
-
- "Command line", [
- "meteor help",
- "meteor run",
- "meteor create",
- "meteor deploy",
- "meteor logs",
- "meteor update",
- "meteor add",
- "meteor remove",
- "meteor list",
- "meteor mongo",
- "meteor reset",
- "meteor bundle"
+ "Meteor.deps", [
+ {name: "Meteor.deps.Context", id: "context"}, [
+ {instance: "context", name: "run"},
+ {instance: "context", name: "on_invalidate"},
+ {instance: "context", name: "invalidate"}
+ ],
+ {name: "Meteor.deps.Context.current", id: "current"}
+ // ],
+
+ // "Environment Variables", [
+ // "Meteor.EnvironmentVariable", [
+ // {instance: "env_var", name: "get", id: "env_var_get"},
+ // {instance: "env_var", name: "withValue", id: "env_var_withvalue"},
+ // {instance: "env_var", name: "bindEnvironment", id: "env_var_bindenvironment"}
+ // ]
]
- ]
+ ],
+
+ "Packages", [ [
+ "amplify",
+ "backbone",
+ "coffeescript",
+ "jquery",
+ "less",
+ "showdown",
+ "underscore"
+ ] ],
+
+ "Command line", [ [
+ "meteor help",
+ "meteor run",
+ "meteor create",
+ "meteor deploy",
+ "meteor logs",
+ "meteor update",
+ "meteor add",
+ "meteor remove",
+ "meteor list",
+ "meteor mongo",
+ "meteor reset",
+ "meteor bundle"
+ ] ]
];
var name_to_id = function (name) {
- var x = name.toLowerCase().replace(/[^a-z0-9_,]/g, '').replace(/,/g, '_');
+ var x = name.toLowerCase().replace(/[^a-z0-9_,.]/g, '').replace(/[,.]/g, '_');
return x;
};
diff --git a/docs/client/packages/backbone.html b/docs/client/packages/backbone.html
index 40bc8517da2..f6ad1763eb6 100644
--- a/docs/client/packages/backbone.html
+++ b/docs/client/packages/backbone.html
@@ -10,11 +10,5 @@
For more information about Backbone, see
http://documentcloud.github.com/backbone/
-{{#warning}}
-Tighter integration between Backbone models and Meteor data is coming
-soon, along with additional examples and patterns for using Backbone
-with Meteor.
-{{/warning}}
-
{{/better_markdown}}