WebFund 2015W Lecture 10
Resources
Video
The video from the lecture given on February 4, 2015 is available now as an MP4.
Notes
Breaking a few things in notes-demo
In app.js, remove var app = express();
- If you delete this line, app is going to be undefined.
- This becomes a problem because you’d be trying to access parts of an undefined object.
- You get a reference error when doing this.
In app.js, remove var session = require('express-session');
- If this line is deleted you get an error: session is not defined.
- This error comes from the calls in index.js to get the username (
req.session.username
). - Since the session module is not loaded, this code cannot execute correctly.
In index.js, inside the router.get('/', ...)
function, remove error: req.query.error
- This causes problems when the user tries to access pages which require them to be logged in such as /notes and /edit.
- The 'not logged in' error will still show up in the URL but not display the error message on the page itself anymore.
JavaScript in Jade
In index.jade, does the -if(error)
get seen by the browser?
No: take a look at the page source and you will see that there is only the div tag and not the condition.
You must realize:
- When you add any JavaScript into the body of a jade template, it is executed on the server (server side JavaScript) and is not seen by the web browser.
- This idea applies to all JavaScript (that is not contained in a script tag).
- The web browser just gets the result.
Making a pop up box when the web page is loaded
- The
res.render()
calls render a Jade template and and then send them to the browser as an HTML page. - It is inside these Jade templates that code can be added to ensure that JavaScript code is sent along with the HTML to be executed on the client-side.
- Add in a
block header
into index.jade.block header script alert(“Hi there”)
- Most of the time you want to put your JavaScript in a separate file (in the public/
JavaScripts folder) so instead you can do the following:
- In public/JavaScripts create a file called alert.js with contents:
alert(“Hello there again”);
- Change the code in index.jade to be:
block header script(src="javascripts/alert.js")
- In public/JavaScripts create a file called alert.js with contents:
- If we want this script to also be able to run in a terminal, it must be modified.
- We need to check if alert is defined (as it is not defined in a regular terminal running Node) to determine whether or not we are in the browser and have access to the
alert()
function. - If there are no alert boxes, we must display to the console instead.
if (typeof(alert)==="undefined") { myalert = function(s) { console.log(s); // this will output to the console instead of pop up in browser } } for(i=0; i<5; i++) { alert(“Hello there again”); }
typeof()
is a useful functiontypeof(5)
gives you ‘number’.typeof(“hello”)
gives you ‘string’.typeof(foo)
gives you ‘undefined’.- You have to remember that it returns a string.
- When trying to read the source code for scripts on other pages, some are very hard to read.
- Any idea why the code from Google might be really hard to read?
- The JavaScript inside of a page is what powers advertisements.
- If you can figure out the JavaScript you can engineer fake clicks.
- Google obscures the JavaScript to prevent click fraud.
Why do you get an error when you try to log in with ‘hasOwnProperty’?
- In the
router.post('/login',...)
function in index.js, we check for the username in userNotes. - The fact that the userNotes object has a function called
hasOwnProperty
is causing a problem. - We can see that this is an inherited function through the following code example:
> x = {} {} > x.hasOwnProperty() [Function: hasOwnProperty] > y = Object.create(null); {} > y {} > y.hasOwnProperty() undefined
CORRECTION regarding hasOwnProperty()
In lecture we saw that we could break notes-demo by giving hasOwnProperty as a username. This error is because the following code in the login post handler is incorrect:
if (!userNotes[username]) { userNotes[username] = []; }
This code should instead say:
if (!Object.hasOwnProperty(username)) { userNotes[username] = []; }
If you are treating a JavaScript object as an associative array you must explicitly check whether a given key value (property) is present using the hasOwnProperty() method inherited by every object.
Note you can create an object x with no prototype by doing the following:
x = Object.create(null);
However, this is not normally done. Indeed, even if you use a JSON parser objects will have a non-null prototype.
Thus, use hasOwnProperty()!
Adding tags in notes-demo
- We want another field for the notes to hold tags (information about the notes).
- Add a field to display tags in notes.jade:
i= userNotes[i].tags
- Appropriate tag data must be added for Alice in the data structure in index.js to view the change.
- Why didn't we have to pass the tags directly to the jade file?
- Because we just passed in the whole notes object, in this case its called userNotes.
- Since the entire object is passed in, the tags get passed in with it.
- If “tags” was a separate data structure, it would need to be added to index.js to be passed in also.
- To be able to edit the tags we need to go to edit.jade and add
div input#title(type=”text”, name=”tags”, value=note.tags)
- To make sure there is a default tag when we create a new note we look at the
router.get('/new', ...
function in index.js and add an additional attribute to the notes object:tags: “Add tags here”
- But we also need to make sure the tag field actually gets the value when you create
a new note or update one. In index.js, in the
router.post('/update', ...
function we also need to add in:note.tags = req.body.tags
Adding jQuery to a page
- In the header of a Jade file, link the script using
script(src="...")
- You would either have to download the jQuery file to your web app and put it in the
JavaScripts directory or you could make the src a full URL and link it from another
place on the web, ex:
<script src=”//code.jquery.com/jquery-1.11.2.min.js”></script> <script src=”//code.jquery.com/jquery-migrate-1.2.1.min.js></script>
- Why would it be better to use the longer URL?
- It saves bandwidth on your server because you don’t have to serve the file; another website does.
- Users may already have the file cached from other websites so it can save bandwidth for them as well.