meteor day talk
TRANSCRIPT
Overview
1. What is Meteor? Why should I use it?
2. Example App
3. Apps using Meteor
4. Additional Resources
Web + Mobile Tutorial!
Discover Meteor Giveaway
Brandon Bechtel@[email protected]
What is Meteor??
• Not your traditional MVC framework– Instead of html templates over http, data-over-
the-wire (DDP)
– Think Ruby on Rails + Angular.js
– Better yet, think of it as something completely new
– -MongoDB Backend
• Built on top of Node.js – all JavaScript
Framework – meteor.js
• Fulltime meteor core dev team working on tools for the entire developer lifecycle:
– Developer Accounts
– Package Repository – atmospherejs.com
• 1 line command to add or publish packages
– Deploy to web and mobile from same codebase
What is Meteor??Platform – meteor.com
• 195,000 Unique Installs
• 20,357 stars on Github
• 2565 packages on atmosphere
• 134 Meteor Day Meetups across the globe
• $11.2mm in seed funding from @a16z
What is Meteor??Community
Why Meteor??
• Modern UI with less code
– No more web pages with links to navigate, instead modern, fast, JS transitions
• Live updates/hot code deploy
• Reactive – db updates visible in UI immediately, across all clients
• Latency Compensation – super fast!!
Technical Case
• Rapid iteration and MVP development (cheaper)
• All web devs know JS, HTML, and CSS (easy to find tech help)
• Easy for a non-tech founder to get started coding!
Why Meteor??Business Case
Example
• Install:
$ curl https://install.meteor.com/ | sh
• Example App:
$ meteor create --example localmarket
$ cd localmarket
$ meteor
**Only for Mac and Linux, Windows users use nitrous.io
Best Resources
• Discover Meteor (discovermeteor.com)– For learning Meteor from the ground up, this is
the best resource available
• Meteor-talk Google Group– Many friendly developers ready to answer your
questions
• Official Documentation (docs.meteor.com)
• Online Meteor DevShops:– EventMind, Meteor Hacks
Future Developments
• Roadmap.meteor.com
– SEO (Meteor serves entire pages that are rendered in JS)
– SQL Integration
– Server Side Rendering
Tutorial!
• Windows users, open up and register at: http://www.nitrous.io
• Follow along at:
– www.meteor.com/install
Tutorial!
• If you haven’t installed, do so now:
$ curl https://install.meteor.com/ | sh
• Create app:
$ meteor create simple-todos
$ cd simple-todos
$ meteor
With app running, you can view it at localhost:3000
Tutorial – simple-todos.css
Copy and paste from:
https://www.meteor.com/try/2
*Tutorial is to learn Meteor, not CSS
Tutorial – simple-todos.html<head>
<title>Todo List</title></head>
<body> <div class="container">
<header> <h1>Todo List</h1>
</header> <ul>
{{#each tasks}} {{> task}}
{{/each}} </ul>
</div> </body>
<template name="task"><li>{{text}}</li>
</template>
Tutorial – simple-todos.jsif (Meteor.isClient) {
// This code only runs on the client
Template.body.helpers({
tasks: [
{ text: "This is task 1" },
{ text: "This is task 2" },
{ text: "This is task 3" }
]
});
}
Tutorial – Collections (our data)
// At the top of simple-todos.js
Tasks = new Mongo.Collection("tasks");
MongoDB CollectionsData structure can be migrated and modified as desired, no additional code needed. Data is structured similar to JSON.
Tutorial – Collections (our data)
// simple-todos.jsif (Meteor.isClient) {
// This code only runs on the clientTemplate.body.helpers({
tasks: function () { return Tasks.find({});
} });
}
Remember: tasks is the data variable (called expressions) in the template, we are now pulling the data from the database
Tutorial – Forms
<!-- simple-todos.html --><header>
<h1>Todo List</h1> <!-- add a form below the h1 -->
<form class="new-task"> <input type="text" name="text" placeholder="Type to add new tasks" />
</form> </header>
Tutorial – Saving Inputs// simple-todos.js// Inside the if (Meteor.isClient) block, right after Template.body.helpers:Template.body.events({ "submit .new-task": function (event) {
// This function is called when the new task form is submitted
var text = event.target.text.value;
Tasks.insert({ text: text, createdAt: new Date() // current time
});
// Clear form event.target.text.value = "";
// Prevent default form submit return false;
} });
Tutorial – Sorting Results
// simple-todos.jsTemplate.body.helpers({ tasks: function () {
// Show newest tasks first return Tasks.find({}, {sort: {createdAt: -1}});
} });
We are now sorting our tasks based on the createdAt timestamp we added when inserting our task in the collection
Tutorial – Updating and Deleting<!-- simple-todos.html --><!-- replace the existing task template with this code --> <template name="task">
<li class="{{#if checked}}checked{{/if}}"> <button class="delete">×</button>
<input type="checkbox" checked="{{checked}}" class="toggle-checked" />
<span class="text">{{text}}</span> </li>
</template>
We are adding check boxes and a delete button to each saved task
Tutorial – Updating and Deleting// simple-todos.js// In the client code, below everything else Template.task.events({ "click .toggle-checked": function () { // Set the checked property to the opposite of its current value Tasks.update(this._id, {$set: {checked: ! this.checked}});
}, "click .delete": function () { Tasks.remove(this._id);
}});
These event handlers update the db accordingly
Tutorial – Deploy!
$ meteor deploy my_app_name.meteor.com
Deploy your app to Meteor’s servers *need to create a meteor acct to do this
Tutorial – Deploy to Mobile
$ meteor install-sdk android
$ meteor add-platform android
$ meteor run android
Or
$ meteor run android-device
Tutorial – Sessions
<!-- simple-todos.html -->
<!-- add the checkbox to <body> right below the h1 -->
<label class="hide-completed">
<input type="checkbox" checked="{{hideCompleted}}" />
Hide Completed Tasks
</label>
Adding a checkbox to hide completed tasks
Tutorial – Sessions
// simple-todos.js
// Add to Template.body.events
"change .hide-completed input": function (event {
Session.set("hideCompleted", event.target.checked);
}
Adding event handler for checkbox
Tutorial – Sessions// simple-todos.js// Replace the existing Template.body.helpersTemplate.body.helpers({ tasks: function () { if (Session.get("hideCompleted")) {
// If hide completed is checked, filter tasks return Tasks.find({checked: {$ne: true}}, {sort: {createdAt: -1}}
); } else {
// Otherwise, return all of the tasks return Tasks.find({}, {sort: {createdAt: -1}});
} }, hideCompleted: function () { return Session.get("hideCompleted");
} });
Returning tasks expression with completed tasks filtered out if box is checked
Tutorial – Count of Incomplete Tasks
// simple-todos.js
// Add to Template.body.helpers
incompleteCount: function () {
return Tasks.find({checked: {$ne: true}}).count();
}
<!-- simple-todos.html -->
<!-- display the count at the end of the <h1> tag -->
<h1>Todo List ({{incompleteCount}})</h1>
Tutorial – Adding User Accounts
$ meteor add accounts-ui accounts-password
<!-- simple-todos.html -->
{{> loginButtons}}
// simple-todos.js
// At the bottom of the client code
Accounts.ui.config({
passwordSignupFields: "USERNAME_ONLY"
});
Tutorial – Adding User Accounts
// simple-todos.js
Tasks.insert({
text: text,
createdAt: new Date(), // current time
owner: Meteor.userId(), // _id of logged in user
username: Meteor.user().username // username of logged in user
});
Tutorial – Adding User Accounts
// simple-todos.js
{{#if currentUser}}
<form class="new-task">
<input type="text" name="text" placeholder="Type to add new tasks" />
</form>
{{/if}}
<!-- simple-todos.html -->
<span class="text"><strong>{{username}}</strong> - {{text}}</span>
Tutorial – Adding User Accounts
$ meteor add accounts-facebook
$ meteor add accounts-twitter
$ meteor add accounts-github
$ meteor add accounts-google
$ meteor add accounts-meetup
Tutorial – Security
$ meteor remove insecure
Meteor automatically adds insecure package to new projects for getting started.Insecure allows editing of database from client.
We don’t want this on a production app!
Tutorial – Security
Now our client side db operations (insert, update, and remove) don’t work!
We need to replace these with a call to a Meteor Method.
Meteor Methods run on both the client and server to immediately update the local copy of the db (mini-mongo) and speed up operation – latency compensation.
Tutorial – Defining Methods// At the bottom of simple-todos.js, outside of the client-only block Meteor.methods({ addTask: function (text) { // Make sure the user is logged in before inserting a task if (! Meteor.userId()) {
throw new Meteor.Error("not-authorized"); } Tasks.insert({
text: text, createdAt: new Date(), owner: Meteor.userId(), username: Meteor.user().username
}); },
deleteTask: function (taskId) { Tasks.remove(taskId);
},
setChecked: function (taskId, setChecked) { Tasks.update(taskId, { $set: { checked: setChecked} });
} });
Tutorial – Defining Methods// replace Tasks.insert( ... ) with:
Meteor.call("addTask", text);
// replace Tasks.update( ... ) with:
Meteor.call("setChecked", this._id, ! this.checked);
// replace Tasks.remove( ... ) with:
Meteor.call("deleteTask", this._id);
Tutorial – Filtering DataUse Publications and Subscriptions to send the right data
to the right templates instead of sending your whole db to the client!
$ meteor remove autopublish
Tutorial – Publications and Subscriptions
// At the bottom of simple-todos.js
if (Meteor.isServer) {
Meteor.publish("tasks", function () {
return Tasks.find();
});
}
// At the top of our client code
Meteor.subscribe("tasks");