info343/labs/7/writeup.php

<section id="introduction">
   <h3>Introduction</h3>
   
   <p>Today we’ll write a page that can search data from <a class="popup" href="http://www.urbandictionary.com/">Urban Dictionary</a> using Ajax requests.</p>
   
   <figure class="example">
      <a href="images/output.png">
         <img src="images/output.png" alt="Screenshot of the final Urban Dictionary lookup" />
         <figcaption>The final Urban Dictionary lookup appearance.</figcaption>
      </a>
   </figure>
   
   <p><a class="popup" href="http://www.programmableweb.com/apilist">Many popular web sites</a> like Google, Flickr, and Facebook allow others to access their data as text and/or XML. For this lab, we will access data from <a class="popup" href="http://www.urbandictionary.com/">Urban Dictionary</a>, a web site that catalogues slang and social terminology. <em>(NOTE: Some content on Urban Dictionary may be considered offensive.)</em></p>
   
   <p>We have created a service named urban.php on Webster that serves Urban Dictionary content. Pass it a term parameter, and it returns the term’s definition as text. For example, for the term “API”:</p>
   
   <p class="resource"><a href="https://info343.ischool.uw.edu/labs/7/urban.php?term=API">https://info343.ischool.uw.edu/labs/7/urban.php?term=API</a></p>
</section>

<section>
   <?= t_head('Load JavaScript File', 5) ?>

   <p>Download the following HTML file:</p>

   <p class="resource"><a href="urban.html">urban.html</a></p>

   <p>This file contains the skeleton of a search page for Urban Dictionary. You will fetch information from the web service using Ajax requests and inject it into the page.</p>

   <p>You’ll need to create your <samp>urban.js</samp> file and ensure it is linked properly by placing <strong>only</strong> an <code>alert</code> statement at the <strong>top of the file</strong>. The page already links to the jQuery library.</p>
</section>

<section>
   <?= t_head('Basic Ajax Request: Inject Single Definition', '5–10') ?>

   <p>First, write the necessary JavaScript code to make the “Lookup” button initiate an Ajax request to the following URL:</p>

   <p><samp>https://info343.ischool.uw.edu/labs/7/urban.php</samp></p>

   <p>Make the request pass a parameter called <code>term</code> whose value is the contents of the text box.</p>

   <p class="note">Pass the parameter using the jQuery <code>data</code> option, not by adding it to a query string.</p>

   <p>The server program will return the definition for the given word.</p>

   <ul>
      <li>Begin by <code>alert</code>ing the definition returned.</li>
      <li>Then inject the definition into the <code>div</code> with the <code>id</code> of <code>result</code>.</li>
   </ul>

   <p class="note important"><strong>Important:</strong> Make sure the <strong>Net</strong> tab is Enabled in Firebug, then refresh your page and make sure you see Ajax requests show up when they’re made.</p>
</section>

<section>
   <?= t_head('Single Definition From XML/JSON', '20') ?>

   <p>Our Urban Dictionary lookup service can also send data in <strong>XML or JSON format</strong>. This way it can return <strong>multiple definitions</strong>, and each definition comes with an example <strong>usage</strong>, as well as other information like an <strong>ID number</strong>, some <strong>user rating</strong> information, and a <strong>permanent link</strong> to the Urban Dictionary page containing that entry.</p>

   <p>To get XML or JSON data, pass our service a parameter <code>format</code>, set to <code>xml</code> or <code>json</code>. The following are example calls to each and their output:</p>

   <p class="resource"><a href="https://info343.ischool.uw.edu/labs/7/urban.php?term=API&amp;format=xml">https://info343.ischool.uw.edu/labs/7/urban.php?term=API<strong>&amp;format=xml</strong></a></p>

<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;entries term=&quot;api&quot;&gt;
  &lt;entry defid=&quot;689981&quot; thumbsup=&quot;199&quot; thumbsdown=&quot;17&quot;
         permalink=&quot;http://api.urbanup.com/689981&quot;&gt;
    &lt;definition&gt;
      API = application programming interface
      An API is a series of functions that ...
    &lt;/definition&gt;
    &lt;example&gt;
      Windows uses an api called the Win32 API. ...
    &lt;/example&gt;
  &lt;/entry&gt;
  &lt;entry defid=&quot;5114162&quot; thumbsup=&quot;4&quot; thumbsdown=&quot;10&quot;
         permalink=&quot;http://api.urbanup.com/5114162&quot;&gt;
    &lt;definition&gt;
      Active pharmaceutical ingredient. The part ...
    &lt;/definition&gt;
    &lt;example&gt;
      The API of aspirine is acetylsalicylic acid.
    &lt;/example&gt;
  &lt;/entry&gt;
  &lt;entry defid=&quot;2650554&quot; thumbsup=&quot;35&quot; thumbsdown=&quot;44&quot;
         permalink=&quot;http://api.urbanup.com/2650554&quot;&gt;
    &lt;definition&gt;
      Adaptive Pie Interface. Used by various ...
    &lt;/definition&gt;
    &lt;example&gt;
      \$urb = new Urban::API;
      \$urb-&gt;ServePie(&#x27;me&#x27;);
      ...
    &lt;/example&gt;
  &lt;/entry&gt;

  ...
&lt;/entries&gt;</code></pre>

   <p class="resource"><a href="https://info343.ischool.uw.edu/labs/7/urban.php?term=API&amp;format=json">https://info343.ischool.uw.edu/labs/7/urban.php?term=API<strong>&amp;format=json</strong></a></p>

<pre><code>[
    {
        "defid": 689981,
        "word": "API",
        "author": "Nathanmx",
        "permalink": "http://api.urbanup.com/689981",
        "definition": "API = application programming …",
        "example": "Windows uses an api called the …",
        "thumbs_up": 217,
        "thumbs_down": 22,
        "current_vote": ""
    },
    {
        "defid": 2650554,
        "word": "API",
        "author": "Tyler Menezes",
        "permalink": "http://api.urbanup.com/2650554",
        "definition": "Adaptive Pie Interface. Used …",
        "example": "\$urb = new Urban::API;\\r\\n\$urb->…",
        "thumbs_up": 37,
        "thumbs_down": 48,
        "current_vote": ""
    },
    {
        "defid": 5114162,
        "word": "API",
        "author": "Wolfy_",
        "permalink": "http://api.urbanup.com/5114162",
        "definition": "Active pharmaceutical ingredient. …",
        "example": "The API of aspirine is acetylsalicylic …",
        "thumbs_up": 6,
        "thumbs_down": 11,
        "current_vote": ""
    },
    {
        "defid": 5178916,
        "word": "API",
        "author": "xyanide1986",
        "permalink": "http://api.urbanup.com/5178916",
        "definition": "Short for Awkward Penis Insertion; …",
        "example": "Guy example: \\"Man this is kind of …",
        "thumbs_up": 10,
        "thumbs_down": 26,
        "current_vote": ""
    }
]</code></pre>

   <ol>
      <li>Choose one of these formats to get your data.</li>
      <li>
         <p>Begin by fetching only the word’s <strong>first definition</strong> from the XML/JSON, and insert three new paragraphs into the <code>result</code> div, containing:</p>
         <figure class="example">
            <a href="images/output2.png">
               <img src="images/output2.png" alt="A single definition, with example, injected into the page" />
               <figcaption>A single definition, with example, injected into the page.</figcaption>
            </a>
         </figure>
         <ol>
            <li>the definition text</li>
            <li>the word’s example usage (give it a <code>class</code> of <code>example</code>)</li>
            <li>a permanent link to that particular Urban Dictionary definition, with the text “Permalink”</li>
         </ol>
      </li>
      <li>If you choose to get your data in XML format, don’t forget to use the DOM’s <code>getElementsByTagName</code> and <code>getAttribute</code> methods on the XML DOM document passed to your callback.</li>
   </ol>
</section>

<section>
   <?= t_head('All Definitions', '10–15') ?>

   <figure class="example">
      <a href="images/output3.png">
         <img src="images/output3.png" alt="All definitions injected into the page" />
         <figcaption>All definitions injected into the page.</figcaption>
      </a>
   </figure>

   <p>Now modify your code to show the three paragraphs about <strong>each</strong> of the definitions of the word.</p>

   <ul>
      <li>Use the DOM to create an ordered list (<code>ol</code>) and add that list to the page.</li>
   
      <li>Inside your list, place a list item for each entry with the 3 paragraphs from last exercise.</li>
   </ul>
</section>

<section>
   <?= t_head('Error Message', '5–10', array('extra' => true)) ?>

   <p>Currently the page will fail inelegantly if the word is not in the dictionary: the web service will return an error code status of <code>404 Not Found</code> if the word does not exist. This will either result in failing silently with a JavaScript error, or (if you’ve added the <code>ajaxError</code> function from the lecture slides) will result in an alert error message.</p>

   <p>To fix this, modify your page so that if the server returns a status code of <code>404 Not Found</code>, you inject a user-friendly error message somewhere into the page indicating that the word was not in the dictionary.</p>

   <p>Remember to clear the error message the next time the user clicks “Lookup”, so they can correct the term entered and see new results without the error persisting.</p>

   <p>To do this you’ll need to add an Ajax error function (if you haven’t already), and adapt it to handle an error code of <code>404</code> differently from other errors. To check the error code, if the first parameter to your error function is called <code>jqxhr</code>, you can inspect <code>jqxhr.status</code>.</p>
</section>

<section>
   <?= t_head('Advanced: Extra Features', '10–15', array('extra' => true)) ?>

   <p>If you’ve finished everything else, try doing some of the following.</p>

   <ul>
      <li>Add the “thumbs up” and “thumbs down” numbers to the page as well. Use the following images: <img src="http://info343.ischool.uw.edu/labs/7/thumbsup.gif" alt="Thumbs up" /> <img src="http://info343.ischool.uw.edu/labs/7/thumbsdown.gif" alt="Thumbs down" /></li>
      <li>Add a <strong>“Loading” animation image</strong> that will temporarily occupy the <code>result</code> area while the data is being fetched via Ajax. You can either use <a class="popup" href="http://info343.ischool.uw.edu/labs/7/loading.gif">this image</a> or create your own from the Ajax loading image site, <a class="popup" href="http://www.ajaxload.info/">ajaxload.info</a>.</li>
      <li>
         <p>You may have noticed that the web service returning a <code>404</code> error code makes it difficult to distinguish between a nonexistent term and accidentally requesting the wrong URL. This ambiguity is a drawback of having the web service return the <code>404 Not Found</code> error code to indicate nonexistence of the term.</p>
      
         <p>However, we can still differentiate between the two cases. For added robustness, you can check <code>ajax.responseText</code> to see whether it looks like the response you expect from the web service. The service’s “not found” messages adhere to the following format, using the example of the nonexistent term “fmord”:</p>
      
         <pre>No definitions found for the term 'fmord'.</pre>
      
         <p>Use a regular expression to see whether the message returned by the web service matches this for any term. This way you can differentiate between a <code>404</code> error caused by loading the wrong page, and one the service returned intentionally to indicate the term was not in the dictionary.</p>
      </li>
   </ul>
</section>

<footer>
   <p>If you’ve finished everything, good job! Experiment with other things you can do with the data retrieved.</p>
</footer>