WebFund 2015W Lecture 10: Difference between revisions
No edit summary |
|||
Line 8: | Line 8: | ||
==Notes== | ==Notes== | ||
<h3>Breaking a few things in notes-demo</h3> | |||
In app.js, remove <code>var app = express();</code> | |||
<ul> | |||
<li>If you delete this line, app is going to be undefined.</li> | |||
<li>This becomes a problem because you’d be trying to access parts of an undefined | |||
object.</li> | |||
<li>You get a reference error when doing this.</li> | |||
</ul> | |||
In app.js, remove <code>var session = require('express-session');</code> | |||
<ul> | |||
<li>If this line is deleted you get an error: session is not defined.</li> | |||
<li>This error comes from the calls in index.js to get the username (<code>req.session.username</code>).</li> | |||
<li>Since the session module is not loaded, this code cannot execute correctly.</li> | |||
</ul> | |||
In index.js, inside the <code>router.get('/', ...)</code> function, remove <code>error: req.query.error</code> | |||
<ul> | |||
<li>This causes problems when the user tries to access pages which require them to be logged in such as /notes and /edit.</li> | |||
<li>The 'not logged in' error will still show up in the URL but not display the error message on the page itself anymore.</li> | |||
</ul> | |||
<h3>JavaScript in Jade</h3> | |||
In index.jade, does the <code>-if(error)</code> 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: | |||
<ul> | |||
<li>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.</li> | |||
<li>This idea applies to all JavaScript (that is not contained in a script tag).</li> | |||
<li>The web browser just gets the result.</li> | |||
</ul> | |||
<h4>Making a pop up box when the web page is loaded</h4> | |||
<ul> | |||
<li>The <code>res.render()</code> calls render a Jade template and and then send them to the browser as an HTML page.</li> | |||
<li>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.</li> | |||
<li>Add in a <code>block header</code> into index.jade. | |||
<code><pre> | |||
block header | |||
script alert(“Hi there”) | |||
</pre></code> | |||
</li> | |||
<li>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: | |||
<ul> | |||
<li>In public/JavaScripts create a file called alert.js with contents: <code>alert(“Hello there again”);</code></li> | |||
<li>Change the code in index.jade to be: | |||
<code><pre> | |||
block header | |||
script(src="javascripts/alert.js") | |||
</pre></code> | |||
</li> | |||
</ul> | |||
</li> | |||
<li>If we want this script to also be able to run in a terminal, it must be modified.</li> | |||
<li>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 <code>alert()</code> function.</li> | |||
<li>If there are no alert boxes, we must display to the console instead. | |||
<code><pre> | |||
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”); | |||
} | |||
</pre></code> | |||
</li> | |||
<li><code>typeof()</code> is a useful function | |||
<ul> | |||
<li><code>typeof(5)</code> gives you ‘number’.</li> | |||
<li><code>typeof(“hello”)</code> gives you ‘string’.</li> | |||
<li><code>typeof(foo)</code> gives you ‘undefined’.</li> | |||
<li>You have to remember that it returns a string.</li> | |||
</ul> | |||
</li> | |||
<li>When trying to read the source code for scripts on other pages, some are very hard to read.</li> | |||
<li>Any idea why the code from Google might be really hard to read? | |||
<ul> | |||
<li>The JavaScript inside of a page is what powers advertisements.</li> | |||
<li>If you can figure out the JavaScript you can engineer fake clicks.</li> | |||
<li>Google obscures the JavaScript to prevent click fraud.</li> | |||
</ul> | |||
</li> | |||
</ul> | |||
<h3>Why do you get an error when you try to log in with ‘hasOwnProperty’?</h3> | |||
<ul> | |||
<li>In the <code>router.post('/login',...)</code> function in index.js, we check for the username in userNotes.</li> | |||
<li>The fact that the userNotes object has a function called <code>hasOwnProperty</code> is causing a problem.</li> | |||
<li>We can see that this is an inherited function through the following code example: | |||
<code><pre> | |||
> x = {} | |||
{} | |||
> x.hasOwnProperty() | |||
[Function: hasOwnProperty] | |||
> y = Object.create(null); | |||
{} | |||
> y | |||
{} | |||
> y.hasOwnProperty() | |||
undefined | |||
</pre></code> | |||
</li> | |||
</ul> | |||
===CORRECTION regarding hasOwnProperty()=== | ===CORRECTION regarding hasOwnProperty()=== | ||
Line 36: | Line 145: | ||
Thus, use hasOwnProperty()! | Thus, use hasOwnProperty()! | ||
<h3>Adding tags in notes-demo</h3> | |||
<ul> | |||
<li>We want another field for the notes to hold tags (information about the notes).</li> | |||
<li>Add a field to display tags in notes.jade: <code>i= userNotes[i].tags</code></li> | |||
<li>Appropriate tag data must be added for Alice in the data structure in index.js to view the change.</li> | |||
<li>Why didn't we have to pass the tags directly to the jade file? | |||
<ul> | |||
<li>Because we just passed in the whole notes object, in this case its called userNotes.</li> | |||
<li>Since the entire object is passed in, the tags get passed in with it.</li> | |||
<li>If “tags” was a separate data structure, it would need to be added to index.js to be | |||
passed in also.</li> | |||
</ul> | |||
</li> | |||
<li>To be able to edit the tags we need to go to edit.jade and add | |||
<code><pre> | |||
div | |||
input#title(type=”text”, name=”tags”, value=note.tags) | |||
</pre></code> | |||
</li> | |||
<li>To make sure there is a default tag when we create a new note we look at the <code>router.get('/new', ...</code> function in index.js and add an additional attribute to the notes object: <code>tags: “Add tags here”</code></li> | |||
<li>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 <code>router.post('/update', ...</code> function we also need to add in: <code>note.tags = req.body.tags</code></li> | |||
</ul> | |||
<h3>Adding jQuery to a page</h3> | |||
<ul> | |||
<li>In the header of a Jade file, link the script using <code>script(src="...")</code><li> | |||
<li>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: | |||
<br> | |||
<code><pre> | |||
<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> | |||
</pre></code> | |||
</li> | |||
<li>Why would it be better to use the longer URL? | |||
<ul> | |||
<li>It saves bandwidth on your server because you don’t have to serve the file; another website does.</li> | |||
<li>Users may already have the file cached from other websites so it can save bandwidth for them as well.</li> | |||
</ul> | |||
</li> | |||
</ul> |
Revision as of 05:48, 9 February 2015
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 (!userNotes.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.