Course offered by University of London & Goldsmiths, University of London
Note : The version of meteor.js used in the course creates a simpler starter application than currently shipping versions
Table of Contents
- 1. Course Home
- 2. Course Info
- 3. Grades
- 4. Discussion Forums
- 5. Week 1
- 6. Week 2
- 6.1. Learning Objectives:
- 6.2. Introduction
- 6.3. Meteor Distributed Data Model
- 6.4. Create a Collection of Images
- 6.5. Better Start-Up Script, Removing Items From a Collection
- 6.6. Add An Image Rating Function: Updating and Sorting
- 6.7. Implement Image Adding With A Bootstrap Modal
- 6.8. Databases and collections summary
- 7. Week 3
- 7.1. Introduction
- 7.2. User authentication with Meteor.js
- 7.3. Tidying up the design with a navbar
- 7.4. Accessing user information
- 7.5. Customizing the user registration form
- 7.6. Attaching users to images
- 7.7. Filtering images by user
- 7.8. Removing the image filter
- 7.9. Infinite scroll
- 7.10. User authentication summary
- 8. Week 4
1 Course Home
Overview : learn how to create complete, multi-user web sites using the Meteor.js framework and MongoDB
2 Course Info
- We’ll implement: user authentication, security features, reactive templates, and routing using iron router
- We’ll carry out database operations: inserting, removing, updating, sorting, and filtering data
- By the end of the course, we should be able to:
- Install Meteor.js and create a template web app
- Use the Meteor.js packaging system
- Write Meteor.js templates that can reactively display data
- Use MongoDB: insert, remove, and update operations
- Use MongoDB filters to search for and sort data
- Add user authentication functionality to a website
- Control what is displayed on the page using iron:router
- Implement basic security features
- We’ll complete the following assignments:
- A server install
- A programming assignment
- 4 quizzes
- Practice quizzes
- The course is built on top of material from two previous courses in the specialization. Prerequisites include basic HTML, CSS, and JavaScript
3 Grades
- Each week has a quiz worth 12%
- Each week has a peer-graded assignment worth 13%
- Each week you need to review your peers for 13%
- Oddly enough, this adds up to a good deal more than 100%
- Week 1 has a grading lecture that correctly breaks things down Grading and Assessment Information (text)
4 Discussion Forums
- Q : In grading, why does the total add up to more than 100%? Is it so you can get a perfect score without completing every assignment?
- : checked the forums a bit, not much going on
- : checked the forums a bit again, not much going on
- : checked the forums a bit again, not much going on; submitted a question about DRYing out code
- : checked the forums a bit again, not much going on; no answer to my previous question
5 Week 1
- Estimated time = 4h 55m
5.1 Course Overview
5.1.1 Overview (video)
As per the overview: Meteor.js to build multi-user, interactive web apps
5.1.2 Course Outline (text)
As per the Course Info
5.1.3 Grading and Assessment Information (text)
- After each lesson, there are practice quizzes
- Practice quizzes don’t count towards your grade for the course
- Grading breakdown:
- Each quiz (x4) = 10%
- Each peer assessment (x2) = 30%
- Pass mark = 65%
5.1.4 Why Meteor? (text)
- Applications in Javascript, CSS, and HTML – no other server-specific language required
- Uses an adapted version of the handlebars template library (used in a previous course in the specialization)
- Provides easy-to-install dev environment that includes a web server and a database server
- Provides an easy-to-use packaging system
- Provides reactive data sources with a distributed data model so that apps will feel snappy to multiple users
- Includes the capability to generate native iOS and Android apps from the same Javascript code base
- Implements an isomorphic model so that you can run the same code base on the server and the client
- Apps can be deployed on any server with Node.js and MongoDB support
5.2 Introduction
5.2.1 Overview (video)
- Get up and running with Meteor.js : install, get first app up and running, and check it out in the web browser; then explore templates; then add user interactivity
5.2.2 URL for This Module (text)
5.2.3 Code for this Module (text)
- I downloaded the code
- I installed meteor via the instructions on the meteor webpage
- I ran
meteor npm install
- I ran
meteor update --patch
- I ran
meteor
et voila! Site available at localhost:3000
5.3 From One to Many Users
5.3.1 From one to many users (video)
- Previous courses in this specialization have worked on sites for single users
- Review of the stack so far: { HTML, CSS, Javascript + Templates, Data } -> Web Browser
- New addition to the stack: the Server (with Meteor.js)
5.3.2 From one to many users (quiz)
- Simple, 2-question quiz
5.4 Install Meteor
5.4.1 URL for this lesson (text)
5.4.2 Install Meteor (video)
- Start by installing meteor, create a starter application, and run the application
- You can create a folder to create your application within; in there, you’d use:
meteor create <application_name>
- If you use meteor create, it’ll create a boilerplate application
5.4.3 Install Meteor (quiz)
- Simple, 2-question quiz
5.5 Editing a Template
5.5.1 URL for this lesson (text)
5.5.2 Editing a template (video)
- Finding out what the boilerplate files out, and how to implement templates the Meteor way
- Template = SpaceBars, derived from HandleBars
- I never knew that you could use open ./ to open Finder in the current directory your terminal is in
- What does
{{> hello}}
mean? Should review handlebars.{{
triggers the template;> hello
means find the hello template and render it <template name="hello"> ... </template>
- You can use the inspector in chrome to see exactly what was sent to the browser
- In meteor, a “public” folder in the web application folder will hold static assets
5.5.3 Editing a template (quiz)
- Simple, 2-question quiz
5.6 Sending Data to Templates with Helpers
5.6.1 Sending data to templates with helpers (video)
- Javascript -> HTML template
- Tests for code running in client or in server
- Template helpers send data to template
- e.g.
var image_data = { img_src: "laptops.jpg", img_alt: "some laptops" }; Template.images.helpers(image_data);
- Then you could use
{{> images}}
and<img src="img_src" alt="img_alt" />
- To pass an array in, you’d need to do something like
Template.images.helpers({images:image_data})
- Iteration via
{{#each images }} ... {{/each}}
5.6.2 Sending data to templates with helpers (quiz)
- Simple, 2-question quiz
5.7 Convert to a Bootstrap Grid
5.7.1 URL for this lesson (text)
- https://atmospherejs.com/ : a catalog for meteor packages
5.7.2 Convert to a Bootstrap Grid (video)
- Additional functionality provided via packages
- Like brew, package, etc.
- We want to install the Bootstrap package!
meteor search .
will download and display the latest list of packagesmeteor search twbs
will display packages that match the twbs terms (like the Twitter Bootstrap package)- Packages are added on a per-application basis
- In our application, we use
meteor add twbs:bootstrap
- We don’t need to edit anything, bootstrap will automatically be used
- Meteor checks your HTML and won’t run the app unless it’s valid
5.7.3 Convert to a Bootstrap Grid (quiz)
- Simple, 2-question quiz
5.8 Responding to User Actions
5.8.1 Responding to user actions (video)
- Basic interactivity!
- JS file where the “serious work” takes place
- Add class to tag like class=”js-image”; might want to prefix interactive classes with js to indicate they’re not layout based
Template.images.events({'click .js-image':function(event){ ... }});
- You can bind data and event listeners in templates
- event.target lets you access the HTML tag in the DOM
- You can use jQuery-style e.g.
$(event.target).css("width", "50px");
5.8.2 Responding to user actions (quiz)
- Simple, 2-question quiz
5.9 Introduction to Meteor Summary
5.9.1 Introduction to Meteor Summary (video)
- Brief recap
5.9.2 Introduction to Meteor Summary (quiz)
- More substantial 10-question quiz
- I filled the form out, but realized that I couldn’t submit it without paying
5.9.3 Peer-graded Assignment (assignment)
- I haven’t upgraded, so I won’t be able to submit the assignment
- I DID, however, DO the assignment
- I downloaded Meteor on my Mac via
curl https://install.meteor.com/ | sh
- I created my app via
meteor create my_first_app
, the resulting text in the console was:
Created a new Meteor app in 'my_first_app'. To run your new app: cd my_first_app meteor npm install meteor If you are new to Meteor, try some of the learning resources here: https://www.meteor.com/learn meteor create --bare to create an empty app. meteor create --full to create a scaffolded app.
- I ran the app via
meteor
(from within the app directory) and viewed it in my web browser by navigating tolocalhost:3000
- It was crashing initially, I used
meteor npm install --save babel-runtime
and restarted my app withmeteor
et voila! - I edited the h1 tag in my application’s client/main.html file as per the instructions and reloaded my browser
5.9.4 Review Your Peers
- I haven’t upgraded, so I won’t be able to review my peers
6 Week 2
6.1 Learning Objectives:
- Create a mongodb collection
- Use mongodb find and insert operations
- Operate a Bootstrap modal from Meteor
- Use 3rd party Meteor packages to add functionality
6.2 Introduction
6.2.1 Overview (video)
- 3 key operations in using databases: insertion, update, and deletion
- Using mongodb (built in with Meteor.js)
6.2.2 URL for this module (text)
6.2.3 Code for this module (text)
- I downloaded the two zip files
6.3 Meteor Distributed Data Model
6.3.1 Meteor distributed data model (video)
- Meteor apps are slightly different from most other web applications with respect to data models
- Each user has their own local copy of the data: people will see data changes in pseudo-realtime
- Changes by a user are propagated back to the central database (reactive)
- Then propagations go back out to all other users
6.3.2 Meteor distributed data model (quiz)
- Simple, 2-question quiz
6.4 Create a Collection of Images
6.4.1 Create a collection of images (video)
- See the theory in practice: store image data in a database
- In mongo, data are called collections
- e.g.
Images = new Mongo.Collection("images");
- e.g.
console.log(Images.find().count());
- We can put starter data in the database
- We can create a new file called startup.js
- In startup.js, we check if we’re running on the server, if there’s nothing in the collection, we’ll add some starter data (but only when the app is starting up)
if( Meteor.isServer ){ Meteor.startup(function(){ etc. }); }
meteor reset
from the command line will wipe all of your databases (!careful!)
6.4.2 Create a collection of images (quiz)
- Simple, 2-question quiz
6.5 Better Start-Up Script, Removing Items From a Collection
6.5.1 Better start-up script, removing items from a collection (video)
- The lecturer DRY’d out the previous startup.js code : loop to add images to collections
- Next up : allow template to access the data
- In
image_share.js
: we useTemplate.images.helpers({images:Images.find()})
- Lecturer modified CSS file to style thumbnail (min & max height = 500px)
- Lecturer went to template in
image_share.html
and added a “delete” button; class=”js-del-image btn btn-warning” - The “js-del-image” lets us know that we need to tie that to an event handler
- In
image_share.js
, we enable the delete functionality via:
Template.images.events({ 'click .js-image':function(event){ $(event.target).css("width", "50px"); }, 'click .js-image-del':function(event){ var image_id = this._id; // this refers to the data the template was displaying; _id is a unique identifier auto-added by mongo console.log( image_id ); Images.remove({ "_id" : image_id }); // this is a mongo filter } })
- We want to use some jQuery to better indicate to the user what’s happening when they click delete
- We add the ID into the template :
<div class="col-xs-12 col-md-3" id="{{_id}}">
- Now, here’s how we hide the component :
$("#" + image_id ).hide('slow', function(){ Images.remove({ "_id" : image_id }); }
- Note that we move the remove command into the hide function
6.5.2 Better start-up script, removing items from a collection (quiz)
- Simple, 2-question quiz
6.6 Add An Image Rating Function: Updating and Sorting
6.6.1 URL for this lesson (text)
6.6.2 Add an image rating function: updating and sorting (video)
- Let user rate images by setting the number of stars
- Sort images so that highest-rated images are shown first
- 1st : HTML to template (for rating widget); is there a package on atmospherejs? Yup!
- To add the package, we use:
meteor add barbatus:stars-rating
- Then we add a sub-template below our image (the package has given us the template for free)
<p> {{>starsRating mutable=true class="js-rate-image" id=_id }} </p>
_id
is the unique id that mongo gives to the image; the star sub-template is within the image template, so we have access to the data from the images- Now we need to add the star ratings to the database
- We’ll add an event listener
Template.images.events({ ... 'click .js-rate-image':function(event){ console.log("you clicked a star"); var rating = $(event.currentTarget).data("userrating"); console.log(rating); var image_id = this.id; console.log(image_id); Images.update({_id:image_id}, {$set: {rating:rating}})); // Images is the mongodb collection // Images.update takes two arguments: the ID of the image you want to change and the property / value that you want to change } })
- this refers to the data in the template
- Now let’s sort the images by rating in this client portion
Images.find({}, {sort:{rating:-1}});
6.6.3 Add an image rating function: updating and sorting (quiz)
- Simple, 2-question quiz
6.7 Implement Image Adding With A Bootstrap Modal
6.7.1 Implement image adding with a Bootstrap Modal, part 1 (video)
- Allow users to add content directly into database
- Add form as new template:
<body> {{> image_add_form }} ... </body> <template name="image_add_form"> <form class="js-add-image"> <input type="text" name="img_src" /> <input type="text" name="img_alt" /> <button class="btn btn-success">save</button> </form> </template>
- Next step, create an event listener so that the server does something when the user submits the form
Template.image_add_form.events({ 'submit .js-add-image':function(event){ var img_src, img_alt; img_src = event.target.img_src.value; // not jQuery because it's a form so we have access to the data more readily img_src = event.target.img_alt.value; Images.insert( { img_src:img_src, img_alt:img_alt, createdOn:new Date() } ); console.log("src: " + img_src + " alt: " + img_alt ); return false; } });
- By default, submit will overwrite console (return false prevents this)
- From the user perspective, it might be confusing because the image went to the bottom of the list; we’ll use createdOn to help with this
Template.images.helpers({ images: Images.find({}, {sort:{createdOn: -1, rating: -1}}) });
6.7.2 Implement image adding with a Bootstrap Modal, part 2 (video)
- The form should look a little bit nicer and be a little more interactive
- We’ll convert the form to sit in a bootstrap modal so that he user can hit a button and the form will appear, then disappear when the user’s done with it
<template name="image_add_form"> <div class="modal fade" id="image_add_form"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <div class="modal-title"> </div> </div> <div class="modal-body"> <!-- form goes here --> </div> <div class="modal-footer"> <button class=""btn btn-warning" data-dismiss="modal">cancel</button> </div> </div> </div> </div> </template>
- This starts hidden, so we need to add a button to the images template
<template name="images"> <button class="btn btn-success js-show-image-form">add image</button> ... </template> Template.image_add_form.events({ ... 'submit .js-add-image':function(event){ ... $("#image_add_form").modal('hide'); // or show?! return false; } 'click .js-show-image-form:function(event){ $("#image_add_form").modal('show'); } })
- Should go onto the bootstrap site to style the form a bit better
6.7.3 Implement image adding with a Bootstrap Modal (quiz)
- Simple, 2-question quiz
6.8 Databases and collections summary
6.8.1 Databases and collections summary (video)
- Recap of week 2!
6.8.2 Databases and collections summary (quiz)
- More substantial 10-question quiz
- I filled the form out, but still can’t submit it without paying
6.8.3 Peer-graded Assignment : Siteace part 1 : edit an event and a template
- Project will be called siteace
- Project will be used in weeks 3 and 4
- Project will become a site that allows users to add web pages they find interesting
- Task this week = complete the implementation of some event code so that websites are saved to the database, edit a template to make website links click-able
- I downloaded and unzipped the starter code
- I ran
meteor npm install --save babel-runtime
in the folder - No errors!
- I ran
meteor
in the folder - I haven’t upgraded, so I won’t be able to submit the assignment
- I DID, however, DO the assignment
- My main.js modification looked like this:
'click .js-add-site':function(event){ var url = $('#url_input').val();// get the form value using jquery... var site = {"url":url};// create a simple object to insert to the collection console.log("You need to put some code in here that calls insert on the Websites collection"); Websites.insert({site:site}); return false; }
- My main.html modification looked like this:
<li><a href="http://{{site.url}}">{{site.url}}</a></li>
I think I completed this assignment a little incorrectly:
- After adding the insert command, sites weren’t automatically showing up in the list, I think this is because I added site, which has a url sub-field instead of just adding url directly
- If you add sites without http[s], then it’ll automatically try to create a local link. I fixed this by prefixing the href with http. That’s brittle.
6.8.4 Review your peers : Siteace part 1 : edit an event and a template
- I haven’t upgraded, so I won’t be able to review my peers
7 Week 3
7.1 Introduction
7.1.1 Overview (video)
- Authentication!
7.1.2 Code for this module (text)
- I downloaded the two zip files
7.2 User authentication with Meteor.js
7.2.1 User authentication with Meteor.js (video)
- Allows a user to log in, and customize the experience for them
- Standard feature for most websites
- A few packages: most basic form = store user accounts in local database
meteor add accounts-ui accounts-password
accounts-ui
: templates for typical user behaviors (log in, reminders)accounts-password
: handles database aspect (user records)- In
image_share.html
, we can add one of the templates we get with accounts-ui
{{> loginButtons }}
- We also get things like emails (on the test server, it’ll be printed to the console)
7.2.2 User authentication with Meteor.js (quiz)
- Simple, 2-question quiz
7.3 Tidying up the design with a navbar
7.3.1 Tidying up the design with a navbar (video)
- Housekeeping!
- Place login functionality in navbar
<nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> {{> loginButtons}} </div> </nav>
- navbar-default : basic styling
- navbar-fixed-top : will always be visible at the top of the page
- Make sure navbar doesn’t lay over things:
body { padding-top: 60px; }
7.3.2 Tidying up the design with a navbar (quiz)
- Simple, 2-question quiz
7.4 Accessing user information
7.4.1 URL for this lesson (text)
7.4.2 Accessing user information (video)
- Dig deeper into user authentication
- We can display the username via something like:
<h1>Welcome to image share, {{username}}!</h1>
- Doesn’t work, yet. Need to provide a template helper function. In
image_js
:
Template.body.helpers({username:function(){ if(Meteor.user){ return Meteor.users().emails[0].address; } else { return "anonymous internet user"; } } });
- The template helper will run twice: as soon as meteor can (in which case the user object won’t exist yet, so it’ll error); and after a user’s logged in, it’ll update that template
- The user will be able to see the anonymous internet user thing briefly
- Next we want to only display the add image button when the user’s logged in:
{{#if currentUser}} <button class="btn btn-success js-show-image-form">add image</button> {{/if}}
- Normally, currentUser would have to be bound to a template, but Meteor binds it to every template for us
7.4.3 Accessing user information (quiz)
- Simple, 2-question quiz
7.5 Customizing the user registration form
7.5.1 URL for this lesson (text)
7.5.2 Customizing the user registration form (video)
- Modifying the user registration form with a username
- We can pass an argument into the account package to do so:
Accounts.ui.config({ passwordSignupFields: "USERNAME_AND_EMAIL" });
- Now we want to greet the user by their username instead of their email:
Template.body.helpers({ username: function(){ if( Meteor.user ){ return Meteor.user.username; } else { return "anonymous internet user"; } } });
7.5.3 Customizing the user registration form (quiz)
- Simple, 2-question quiz
7.6 Attaching users to images
7.6.1 Attaching users to images (video)
- Attach a user account to an image so we know, for each image, which user uploaded it
- In
image_share.js
:
Template.image_add_form.events({ 'submit .js-add-image':function(){ var img_src, img_alt; img_src = event.target.img_src.value; img_alt = event.target.img_alt.value; if( Meteor.user ){ Images.insert({ img_src: img_src, img_alt: img_alt, createdOn: new Date(), createdBy: Meteor.user()._id; }); } $("#image_add_form").modal("hide"); return false; } });
- Javascript notion of truthy (e.g. non-false) and falsey (e.g. non-true, not usable data)
- Now, we want to make sure the user information has been added, so we’ll display it in the image template:
<div class="thumbnail"> ... <div class="caption"> ... <p>User: {{getUser createdBy}}</p> ... </div> </div>
Template.images.helpers({ images:... getUser:function(user_id){ var user = Meteor.users.findOne({ _id:user_id }); if( user ){ return user.username; } else { return "anon"; } } });
- We access users differently than images – even though both are collections – because Meteor handles users slightly differently (security, etc.)
7.6.2 Attaching users to images (quiz)
- Simple, 2-question quiz
7.7 Filtering images by user
7.7.1 URLs for this lesson (text)
7.7.2 Filtering images by user (video)
- Filter to control which images are being displayed (e.g. by a particular user)
- Make username click-able (in template)
<div class="caption"> ... <p> User: <a href="#" class="js-set-image-filter">{{getUser createdBy}}</a> </p> </div>
- Add event listener in Javascript
Template.images.events({ ... 'click .js-set-image-filter':function(event){ Session.set("userFilter", this.createdBy); } })
- Session is a reactive data source that allows us to store temporary variables in key-value pair format
Template.images.helpers({ ... images:function(){ if( Session.get("userFilter") ){ return Images.find({createdBy:Session.get("userFilter")}, {sort: {createdOn:-1, rating:-1}}); } else { return Images.find({}, {sort: {createdOn:-1, rating:-1}}); } }, ... })
7.7.3 Filtering images by user (quiz)
- Simple, 2-question quiz
7.8 Removing the image filter
7.8.1 Removing the image filter (video)
- No new techniques here: just more examples of previously used ones
7.8.2 Removing the image filter (quiz)
- Simple, 2-question quiz
7.9 Infinite scroll
7.9.1 Infinite scroll (video)
- Load data as needed
- Simplest way of implementing an infinite scroll in the image gallery
- Want to capture a scroll event from the browser; hard in the standard meteor way
- We’ll use some slightly hacky jQuery; we also want to limit the initial number of images we show:
if (Meteor.isClient) { Session. set("imageLimit", 8); lastScrollTop = 0; $(window).scroll(function(event){ var scrollTop = $(this).scrollTop(); // test if we're near the bottom of the window if( $(window).scrollTop() + $(window).height() > $(document).height() - 100 ){ // test if we are going down var scrollTop = $(this).scrollTop(); if (scrollTop > lastScrollTop ) { Session.set("imageLimit", Session.get("imageLimit") + 4 ); } lastScrollTop = scrollTop; } }); } ... return Images.find({}, {sort:{createdOn: -1, rating: -1 }, limit:Session.get("imageLimit")});
7.9.2 Infinite scroll (quiz)
- Simple, 2-question quiz
7.10 User authentication summary
7.10.1 User authentication summary (video)
- Recap of week 3!
7.10.2 User authentication summary (quiz)
- More substantial 10-question quiz
- I filled the form out, but still can’t submit it without paying
7.10.3 Peer-graded Assignment : Siteace part 2 : user authentication
- I downloaded and unzipped the starter code
- I ran
meteor npm install --save babel-runtime
in the folder - I haven’t upgraded, so I won’t be able to submit the assignment
- I DID, however, DO the assignment
- I found the assignment very straightforward and not very challenging
7.10.4 Review your peers : Siteace part 2 : user authentication
- I haven’t upgraded, so I won’t be able to submit the assignment
8 Week 4
8.1 Introduction
8.1.1 Overview (video)
- Find out how to deploy sites; “hack” into our own sites to examine security problems; implement security; routing
8.1.2 Code for this module (text)
- I downloaded the two zip files
8.2 How to organize your code
8.2.1 How to organize your code (video)
- As application grows, having all your code in one file becomes hard to maintain
- We can set up special folders which the framework knows about
public
folder used for public / static assets (e.g. images)client
andserver
are two more folders that meteor knows aboutclient
folder would contain all of the info in theMeteor.isClient
blockserver
folder would contain all of the info in theMeteor.isServer
block- I think Meteor applications are set up like this by default now
- You can use
shared
that will have files in use on both (but it’s not a special folder by default) - Collections are shared, so both client and server need access to them
- Other special folders:
private
only server needs to see them and it needs to use the assets API to access themtests
is just a playground and it won’t be sent to the client or the server
8.2.2 How to organize your code (quiz)
- Simple, 2-question quiz
8.3 Hack into your site!
8.3.1 Hack into your site! (video)
- Topic = basic security!
- Some examples of behavior that users shouldn’t have access to (e.g. using the Javascript console to delete all the images in the image database)
8.3.2 Hack into your site! (quiz)
- Simple, 2-question quiz
8.4 Make your site more secure
8.4.1 URL for this lesson (text)
8.4.2 Make your site more secure (video)
- Securing your application : the basics
- By default, Meteor puts a package in that helps you get up-and-running, but isn’t necessary for us
- We use
meteor remove insecure
to remove the “insecure” package - By default, you’re then stopped from doing certain things with the database (e.g. adding pictures)
- We create a
lib
folder; things inlib
will be run first; it’s run on BOTH the client and server - We can put a
collections.js
file in there, along with security information:
Images = new Mongo.Collection("images"); // Set up security Images.allow({ insert:function(userId, doc){ if (Meteor.user()){ doc.createdBy = userId; // force the image to be owned by the current user if( userId != doc.createdBy ){ return false; } else { return true; } } else { return false; } }, remove:function(userId, doc){ if (Meteor.user()){ return true; } } })
8.4.3 Make your site more secure (quiz)
- Simple, 2-question quiz
8.5 Tidy up the project
8.5.1 Tidy up the project (video)
- Cleaning up!
- E.g. server doesn’t need any CSS or HTML files, so we make sure they’re all in the
client
folder - E.g. we can get rid of
if (Meteor.isServer)
if it’s in the server folder; ditto with client
8.5.2 Tidy up the project (quiz)
- Simple, 2-question quiz
8.6 Routing with iron:router
8.6.1 URL for this lesson (text)
8.6.2 Routing with iron:router (video)
- Adding a new feature: routing
- Routing allows you to control which components of the application are shown at any given time
meteor add iron:router
- We can define different places that the user can visit in the application, and we can define different things that’ll be displayed at each point
- We’ll create templates to simplify things: e.g. for the navbar, etc:
<template name="navbar"> ... </template>
- The body tag will be empty; we’ll modify our routes
Router.route('/', function() { this.render('navbar'); }); Router.route('/images', function() { this.render('images'); });
- Next up, rendering multiple templates into a single page
8.6.3 Routing with iron:router (quiz)
- Simple, 2-question quiz
8.7 Better routing
8.7.1 Better routing (video)
- Welcome page, single image, and back again using routing and templates
- In main.js:
Router.configure({ layoutTemplate: 'ApplicationLayout' // default template for layout is ApplicationLayout }); Router.route('/', function() { this.render('welcome', { to: "main" }); }); Router.route('/images', function() { this.render('navbar', { to: "navbar" }); this.render('images', { to: "main" }); }); Router.route('/image/:_id', function() { this.render('navbar', { to: "navbar" }); this.render('image', { to: "main", data: function(){ return Images.findOne({_id:this.params._id}); }}); });
<template name="ApplicationLayout"> {{> yield "navbar" }} {{> yield "main" }} </template> <template name="welcome"> <div class="container"> <div class="jumbotron"> ... </div> </div> </template> <template name="image> <div class="container"> <h2>{{img_alt}}</h2> <a href="/images"><img class="single-img" src="/{{img_src}}" /></a> </div> </template>
- Routes will make the browser back/forward buttons work properly
8.7.2 Better routing (quiz)
- Simple, 2-question quiz
8.8 Security and routing summary
8.8.1 Security and routing summary (video)
- Recap of week 4!
8.8.2 Security and routing summary (quiz)
- More substantial 9-question quiz
- I filled the form out, but still can’t submit it without paying
8.8.3 Peer-graded Assignment : Siteace : implementing discussions
- I downloaded and unzipped the starter code
- I ran
meteor npm install
in the folder - I haven’t upgraded, so I won’t be able to submit the assignment
- I DID, however, DO the assignment
- I found the assignment very straightforward and not very challenging
8.8.4 Review your peers : Siteace : implementing discussions
- I haven’t upgraded, so I won’t be able to submit the assignment