Difference between revisions of "WebFund 2015W Lecture 10"

From Soma-notes
Jump to navigation Jump to search
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 01: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")
      
  • 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 function
    • typeof(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.