{{#pretty}}{{this}}{{/pretty}}
{{/each}}// Publish the entire 'todos' collection to any client that asks for // it, and send updates in realtime. Meteor.publish("todos"); // Publish the 'payments' collection, but exclude payments that are // marked secret. Meteor.publish("payments", {selector: {secret: false}}); // Let clients subscribe to just the posts made by a particular // person. Meteor.publish("user-posts", { collection: Posts, selector: function (params) { return {posted_by: params.who}; } });{{> api_box subscribe}}
on_ready
will likely be removed in a future release and
replaced with a different mechanism.
// Connect to the server, grab the "todos" dataset, and store it in // the appropriate local collections. Listen for changes on the server // and keep the local copy updated. var s = Meteor.subscribe("todos"); // After five seconds, end the subscription and stop receiving updates. setTimeout(function () {s.stop();}, 5000); // Pull down Woudiver's posts. Meteor.subscribe("user-posts", {who: "Woudiver"}); // Find the available rooms, and once they've loaded, select the // first one. Meteor.subscribe("rooms", {}, function () { Session.set("selected-room", Rooms.find()[0]._id); });{{> api_box autosubscribe}}
The easiest way to understand what this function does is to look at the example.
func
will be run immediately, and while it runs,
records will be kept of the subscriptions it makes
(via Meteor.subscribe
) and the data it uses
(including calls to Session.get
and collection.find
).
Whenever the used data changes, the subscriptions will be cancelled
and func
will be re-run to make replacement subscriptions.
It's not necessary to call stop
on subscriptions made
from inside Meteor.subscriptions
.
Example:
// Subscribe to the chat messages in the current room. Automatically // update the subscription whenever the current room changes. Meteor.subscriptions(function () { Meteor.subscribe("chat", {room: Session.get("current-room");}); });
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 and any <body>
templates from
your .html
files have been put on the screen.
Example:
// On server startup, if the database is empty, create some initial data. if (Meteor.is_server) { Meteor.startup(function () { if (Rooms.find().length === 0) { Rooms.insert({name: "Initial room"}); } }); }{{> 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.
Call flush
to apply any 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
or
Meteor.ui.renderList
, have already
been inserted in the main DOM tree.
Technically speaking, flush
calls
the invalidation callbacks on
every reactive context that has been
invalidated, 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
that works through
invalidations.
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
" (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_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 context to get realtime updates.
{{> api_box reconnect}}There is a single API for accessing your data, whether from the client or from the server. Right now the only database supported is MongoDB. When you use the API from the server, you're hitting a real Mongo database. When you use the API from the client, you're hitting a local, in-memory cache called Minimongo. Minimongo has exactly the same API as regular Mongo.
$elemMatch
is not supported in selectors.$pull
in modifiers can only accept certain kinds
of selectors.$
to denote the matched array position is not
supported in modifier.a
,
but not a.b
.)findAndModify
, upsert, aggregate functions, and
map/reduce aren't supported.packages/minimongo/NOTES
in the repository.
Calling this function is analogous to declaring a model in an 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.
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.
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:
find
) are served directly out of
this cache, without talking to the server.update
, remove
),
the command is executed immediately on the client, and,
simultaneously, it's shipped up to the server and executed there
too.Meteor.publish
on the server
and Meteor.subscribe
on the
client. When data comes in from a subscription, the name
s
that were provided when creating the collections are used to insert it
into the correct Minimongo collections.If you don't pass a 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.
// 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) Posts = Meteor.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 any other // collection, but it doesn't send changes to the server, and it // can't receive any data from subscriptions. Scratchpad = Meteor.Collection(); for (var i = 0; i < 10; i++) Scratchpad.insert({number: i * 2}); assert(Scratchpad.find({number: {$lt: 9}}).count() === 5);{{> api_box find}}
Define a query and return a cursor: a reference to that query. Does not immediately access the database or register a data dependency.
Collection cursors track the set of matched database objects the cursor's position within that set. Each of the methods that retrieves data updates the cursor position until the cursor reaches the end of the data set. Collection cursors can be rewound to read through the documents a second time.
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.
Queries are a reactive data source. The first time a cursor's data is
used in a reactive context (eg,
Meteor.ui.render
,
Meteor.autosubscribe
, it will
register a dependency on the underlying data. Any change to that data
that would affect the value of the cursor will trigger a
recomputation. To disable this behavior, pass {reactive: false} as an
option to the original query call.
Immediately return a single document without creating an explicit
cursor. Equivalent to collection.find(selector, options).fetch()[0]
.
// Display a count of posts matching certain criteria. Automatically // keep it updated as the database changes. var frag = Meteor.ui.render(function () { var high_scoring = Posts.find({score: {$gt: 10}}); return $("<p>There are " + high_scoring.length + " posts with " + "scores greater than 10</p>"); }); document.body.appendChild(frag);
When called in a reactive context, count() will trigger a recomputation if the number of matching documents changes. (Updates to a matching document will not trigger a recomputation.)
{{> api_box cursor_foreach}} {{> api_box cursor_map}} {{> 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.
Each of these methods registers a dependency on the full query result. This means, when the cursor is accessed in a reactive context, any change in the query's result set will trigger a recomputation.
Examples:
// Print the titles of the five top-scoring posts var top_posts = Posts.find({}, {sort: {score: -1}, limit: 5}); var count = 0; top_posts.forEach(function (post) { console.log("Title of post " + count + ": " + post.title); count += 1; });{{> api_box cursor_rewind}}
To access the data in a cursor more than once,
call rewind
to reset the cursor to its initial state.
Establishes a live query that is notified on any change to the query result. Observe is only available on the client.
callbacks
may have the following functions as
properties:
added(document, before_index)
before_index
. Or if it was inserted at the end
of the list, before_index
will be equal to the (prior)
length of the list.changed(new_document, at_index)
at_index
changed to new_document
.
moved(document, old_index, new_index)
old_index
to new_index
. For your
convenience, its current contents is document
. (This will
only fire immediately after changed
.removed(id, at_index)
at_index
, which had the
given id
, is no longer in the result set.added
will immediately be called as necessary to
deliver the initial results of the query, if any.
Calling observe
in a reactive context does not
register a dependency on the query.
Returns a live query handle, which is an object with these methods:
stop()
Example:
// Keep track of how many administrators are online. var count = 0; var query = Users.find({admin: true, online_now: true}); var handle = query.observe({ added: function (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);{{> 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 make a copy of the object, add
an _id
attribute that contains a unique ID for the
object, insert it in the database, and return the copy to you.
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
.
upsert
feature is not implemented.
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.
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 $("<div>" + post.name + " <span class='delete'>Delete</span></div>"); }, events: { 'click .delete': function () { Posts.remove(this._id); } } }); document.body.appendChild(frag);
In its simplest form, a selector is just 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 "today" {tags: "popular"} // Matches documents where fruit is one of three possibilities {fruit: {$in: ["peach", "plum", "pear"]}}
See the complete documentation.
A modifer 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.
// Find the document with id "123", and completely replace it. Users.update({_id: "123"}, {name: "Alice", friends: ["Bob"]});
See the full list of modifiers.
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.
Session
is a global object 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("current_list")
from inside a template, the template will automatically be rerendered
whenever Session.set
is called.
Example:
Meteor.autosubcribe(function () { Meteor.subscribe("chat-history", {room: Session.get("current_room")}); }); // Causes the function passed to Meteor.autosubscribe to be re-run, so // that the chat-history subscription is moved to the room "home". Session.set("current_room", "home");
See Meteor.deps
for another
example.
Example:
Session.set("enemy", "Eastasia"); var frag = Meteor.ui.render(function () { return $("<p>We've always been at war with " + Session.get("enemy") + "</p>"); }); // Page will say "We've always been at war with Eastasia" document.body.append(frag); // Page will change to say "We've always been at war with Eurasia" Session.set("enemy", "Eurasia");{{> api_box equals}}
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:
// 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. var frag = Meteor.ui.renderList(Posts, { render: function (post) { var cls = Session.equals("selected_post", post._id) ? "selected" : ""; return $("<div class='" + cls + "'>" + post.title + "</div>"); }, events: { 'click': function () { Session.set("selected_post", this._id); } } }); document.body.appendChild(frag); // In this code, when the user clicks on an item to select it, the // render function is called twice: once to rerender the item // that lost the selection, and once to rerender the item that gained // the selection. // // If Session.get had been used instead of Session.equals, then when // the user clicked on an item, the render function would have to // called once for every Post shown in the list.
These are some utility functions for building interfaces. They make
it easy to create DOM elements that update automatically as data
changes in Session
variables or in
a Collection
.
These helpers are implemented entirely on top of the public
interfaces at
Meteor.Deps
and
Meteor.Collection
.
You provide a function that returns some DOM
elements. Meteor.ui.render
gives you back some DOM elements
that automatically updates themselves in place. They are sensitive to
changes to session variables
(Session.get
) and to database writes
(collection.update
, etc.)
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
is called when the
elements are not children of document
.
events
lets you quickly hook up some event handlers to
the DOM nodes. If you provide event_data
, it will be
passed to event handlers in this
.
Meteor.ui.render
may be called recursively (that
is, render_func
can call Meteor.ui.render
.) If
that happens, each invocation of render
works
independently — an change to a dependency of the
inner render_func
will (correctly) not cause the
outer render_func
to be recomputed.
Example:
// Show the number of users online. var frag = Meteor.ui.render(function () { return $("<p>There are " + Users.find({online: true}).length + " users online.</p>"); }); document.body.appendChild(frag); // Find all users that have been idle for a while, and mark them as // offline. The count on the screen will automatically update. Users.update({idleTime: {$gt: 30}}, {online: false}); // Show a counter, and let the user click to increase or decrease it. Session.set("counter", 0); var frag = Meteor.ui.render(function () { return $('<div>Counter: ' + Session.get("counter") + ' ' + '<span class="inc">Increase</span>' + '<span class="dec">Decrease</span></div>'); }, { 'click .inc': function (event) { Session.set("counter", Session.get("counter") + 1); }, 'click .dec': function (event) { Session.set("counter", Session.get("counter") - 1); } }); document.body.appendChild(frag);{{> api_box renderList}}
This is Meteor.ui.render
crossed
with collection.findLive
It calls a render function repeatedly for each document in a
collection that matches a query.
this
.
Returns a DocumentFragment
with the same semantics as in
Meteor.ui.render
— insert it
anywhere, it will automatically update itself, make sure it's on the
page before the next time you
call Meteor.flush
.
Example:
// List the titles of all of the posts that have the tag // "frontpage". Keep the list updated as new posts are made, as tags // change, etc. Let the user click a post to select it. Session.set("selected", null); var frag = Meteor.ui.renderList(Posts, { render: function (post) { var style = Session.equals("selected", post._id) ? "selected" : ""; // A real app would need to quote/sanitize post._name return $('<div class="' + style + '">' + post._name + '</div>'); }, selector: {tags: "frontpage"}, events: { 'click': function (event) { Session.set("selected", this._id); } } }); document.body.appendChild(frag);
Several functions take event maps. An event map is an object where the properties specify a set of events to handle, and the values are the handlers for those events. The property can be in one of several forms:
The handler function gets one argument, an object with information
about the event. It will receive some additional context data
in this
, depending on the context (eg: with
Meteor.ui.renderList
, you get the
document; with a Handlebars template, you get the data being used to
fill the template.)
Example:
{ // Fires when any element is clicked 'click': function (event) { ... }, // Fires when any element with the 'accept' class is clicked 'click .accept': function (event) { ... }, // Fires when 'accept' is clicked, or a key is pressed 'keydown, click .accept': function (event) { ... } }
Meteor has a simple dependency tracking system, so that it it can
automatically rerender templates and such when
Session
variables are modified, or
database queries change.
Unlike most other systems, you don't have to manually declare these dependencies — it "just works". The mechanism is simple and efficient. When you call a function that supports reactive updates (say, a database query), it automatically saves the current "invalidation context" object if any (say, the current template being rendered.) Later, when the data changes, it can "invalidates" this context (tell the template to rerender itself.) The whole implementation is about 50 lines of code.
As an end user, the only function you need to know about is
Meteor.flush
, which forces all of the
pending updates to complete (for example, it ensures the DOM has been
updated with your recent database changes.) The functions
in Meteor.deps
are provided in case you want to hook into the
invalidation system yourself to write your own reactive functions.
Create an invalidation context by calling this constructor, then run
some code inside the context
with run
. Finally, register a
callback
with on_invalidate
that
will get called when the code you run wants to signal that it should
be rerun.
Code can see if it's running inside an invalidation context by
reading
the Meteor.deps.Context.current
global variable, which will be the currently active context,
or null
if it's not being run from inside a context.
If it wants to participate in the reactivity system, it should save
this context away, and later call
the invalidate
method on the
context when it wants to signal that something has changed. If it
does this, it should also
use on_invalidate
to set
up a cleanup function so that it can know when to stop listening for
changes.
Invalidation contexts have an attribute id
which is a
unique positive integer. You're free to add any other attributes you
like to the invalidation context for your own convenience, as long
as they don't start with an underscore.
This is a global variable that is set by
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
sets it, runs some user-supplied code, and then restores its previous
value.)
This function simply sets
Meteor.deps.Context.current
to this
invalidation context, runs func
, and then restores it
to its previous value. It returns the result of
calling func
.
It's fine for run
to be called
recursively. current
will return the innermost context.
If this context hasn't been invalidated yet,
adds callback
to the list of callbacks that will be
called when invalidate
is
called. If the context has already been invalidated,
call callback
immediately.
Typically this function will have two kinds of callers:
on_invalidate
callback as a signal to rerun the
code in the context, to see what new value it returns. In order to
rerun the code, it'll create a fresh invalidation context and
reregister its on_invalidate
callback on that new
context. When that context is invalidated the cycle will repeat.
Meteor.deps.Context.current
into
some kind of list of listeners. They'll use
the on_invalidate
callback to remove the context from
their listener list.
Example:
// Print the current username to the console. Will re-run every time // the username changes. var log_current_username = function () { var update = function () { var ctx = new Meteor.deps.Context(); // invalidation context ctx.on_invalidate(update); // rerun update() on invalidation ctx.run(function () { var username = Session.get("username"); console.log("The current username is now", username); }); }; update(); }; // Example use. Since Session is reactive (meaning that it knows how // to use Meteor.deps to record its dependencies), log_current_username // will be re-run whenever Session.set is called for "username". Session.set("username", "matt"); log_current_username(); // prints matt Session.set("username", "geoff"); // immediately prints geoff Session.set("username", "geoff"); // won't print: Session won't trigger // invalidation if the value is the same.{{> api_box invalidate }}
If this function has already been called on this context, it does
nothing (a mathematician would say that it is "idempotent.") Otherwise
it calls each on_invalidate
function registered on the context.
The functions aren't called immediately — instead, they will
be called the next time you call
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
explicitly, it will be called for you automatically when your code is
done running (by setting a setTimeout
timer with a delay
of zero.)
Example:
// Create a simple class called Weather that tracks the current // temperature. The temperature can be read reactively. var Weather = function () { this.temperature = 60; this.listeners = {}; }; // Function to get the temperature (and, if called in a reactive // context, start listening for changes to the temperature.) Weather.prototype.get_temp = function () { var context = Meteor.deps.Context.current; // If we're inside a context, and it's not yet listening to // temperature changes.. if (context && !this.listeners[context.id]) // .. add it to our list of contexts that care about the temperature .. this.listeners[context.id] = context; // .. and remember to take it off our list when it goes away. var self = this; context.on_invalidate(function () { delete self.listeners[context.id]; }); } // return the current temperature, whether or not in a reactive context. return this.temperature; }; // Function to set the temperature, and notify anyone that might be // listening for temperature updates. Weather.prototype.set_temp = function (new_temp) { if (this.temperature === new_temp) return; // don't want to trigger invalidation if there's no change. // Set the temperature this.temperature = new_temp; // Notify any contexts that care about temperature changes for (var context_id in this.listeners) // This will trigger the on_invalidate function above, but not // immediately -- only when Meteor.flush() is called, or at the end // of the event loop. So we know that this.listeners will be // emptied, but it won't change while we're trying to loop over it. this.listeners[context_id].invalidate(); };
Get help on meteor command line usage. Running meteor
help
by itself will list the common meteor
commands. Running meteor help command
will print
detailed help about the command.
Run a meteor development server in the current project. Searches upward from the current directory for the root directory of a Meteor project. Whenever you change any of the application's source files, the changes are automatically detected and applied to the running application.
You can use the application by pointing your web browser at localhost:3000. No internet connection is required.
This is the default command. Simply running meteor
is the
same as meteor run
.
Run meteor help run
to see the full list of options.
Create a new Meteor project. Makes a subdirectory named name and copies in the template app. You can pass an absolute or relative path.
Deploy the project in your current directory to Meteor's servers.
You can deploy to any available name
under meteor.com
without any additional
configuration, for example, myapp.meteor.com
. If
you deploy to a custom domain, such as myapp.mydomain.com
,
then you'll need to make sure the DNS for that domain is configured to
point at origin.meteor.com
.
You can deploy in debug mode by passing --debug
. This
will leave your source code readable by your favorite in-browser
debugger, just like it is in local development mode.
To delete an application you've deployed, specify
the --delete
option along with the site.
To add an administrative password to your deployment, include
the
option. Meteor will prompt
for a password. Once set, any future meteor deploy
to
the same domain will require that you provide the password. The same
password protects access to meteor mongo
and meteor logs
. You can change the password by
running meteor deploy
again,
which will first prompt for the current password, then for a new
password.
meteor.com
you must ensure that the name resolves
to origin.meteor.com
. If you want a top-level
domain like myapp.com, you'll need a DNS A record, matching the IP
address of origin.meteor.com.
Retrieves the server logs for the named Meteor application.
Meteor redirects the output of console.log()
in your
server code into a logging server. meteor logs
displays those logs. In client code, the output
of console.log()
is available in your web browser's
inspector, just like any other client-side JavaScript.
Upgrade to the latest Meteor version. Checks to see if a new version of Meteor is available, and if so, downloads and installs it. You must be connected to the internet.
Add packages to your Meteor project. You can add multiple packages
with one command. For a list of the available packages, run meteor
list
.
Removes a package previously added to your Meteor project. For a
list of the packages that your application is currently using, run
meteor list --using
.
Without arguments, lists all available Meteor packages. To add one of
these packages to your project, run meteor add package
.
With --using
, list the packages that you have added to your project.
Open a MongoDB shell on your local development database, so that you can view or manipulate it directly.
meteor run
. This will be easier in the future.
Reset the current project to a fresh state. Removes the local mongo database.
meteor
mongo
. From the mongo shell, use show collections
and db.collection.find()
to inspect your data.
Package the application up for deployment. The output is a tarball
that includes everything necessary to run the
application. See README
in the tarball for details.
You can use this to host a Meteor application on your own server,
instead of deploying to Meteor's servers. You will have to deal with
logging, monitoring, backups, load-balancing, etc, all of which we
handle for you if you use meteor deploy
.