18 March 2012

Hewlett Packard sponsored a coding contest to win a very nice laptop! The goal was to consume was to consume two restful winaspectre web services. You can see some of the entries on Twitter using the #winaspectre hash. Congratulations to all the winners!

NOTE: The JSONP Web Service has since gone down.

My entry while submitted was not complete and I thought I would complete the project discussing where I went wrong. My goal was to list out the speakers creating hyperlinks on their name and lecture titles. When their name is clicked it would search for them on LinkedIn and when their lecture title was clicked it would pull back Google search results. I ran into several problems while writing my submitted effort. My two biggest problems where that I had never before used a JSONP web service before or the LinkedIn API. Between the two I wasted several hours trying to make a standard JSON web service call and trying to anonymously query LinkedIn. See the results.

My submission is shown below and our goal will be to go over the code discuss where I’ve gone wrong and how to achieve something better. The first change I would make is to list all the speakers and their lecture titles. Next I would search for the first speaker listed on LinkedIn and display the results. The third change is to provide the option of logging into LinkedIn. Logging in will give the user better and more detailed information. Once I have done this I will discuss the changes that I made in Part 2.

It would be beneficial for you to become familiar with the LinkedIn APIs and to make sure you are ready to get started. Do not forget to setup your API key! JQuery is the JavaScript API that I am using and is very easy to use if you have basic knowledge of Cascading Style Sheets (CSS).

In Part 2 we will cleanup the code, make the speaker list display by default and improve how the LinkedIn login is handled.

index.html
<html>
 <head>
  <style>
   #container {
     background-color: Gray;
    width: 100%;
    display: block;
    float: left;
   }
    #feedList {
     background-color: Green;
     float: left;
     width: 25%;
     max-width: 25%;
     min-width: 25%;
    } 
     #lineItem {
     background-color: #BBBBBB;
     width: 90%;
     float: left;
     clear: both;
    } 

  </style>
  <script type="text/javascript" src="jquery-1.7.1.js"></script>
  <script type="text/javascript" src="http://platform.linkedin.com/in.js">
      api_key: ###get your own!###
      authorize: true
      onLoad: onLinkedLoad
    </script>
  <script type="text/javascript">
   var lloaded = false
   
   function onLinkedLoad() {
    
     if(IN.User.isAuthorized()) {
      loadData();
     } else {
      hideData();
     }
   }
   
   function showData() {
    //alert("show");
        $("#container").css("display","block");
        $("#feedList").css("display","block");
        $("#lineItem").css("display","block");
        $("#mustLogin").hide();    
   }

   function hideData() {
    //alert("hide");
        $("#container").css("display","none");
        $("#feedList").css("display","none");
        $("#lineItem").css("display","none");
        $("#mustLogin").show();    
   }

   
   function loadData() {
     lloaded = true;
     //alert("lloaded=" + lloaded);
     var jsonUrl="http://winaspectreapi.appspot.com/api/sessions";
        showData();
        
        
        
        buildListAJAX(jsonUrl);
         
   }

      function getLinkedInfo(firstName, lastName) {
       IN.API.PeopleSearch().fields("firstName", "lastName", "distance", "publicProfileUrl","pictureUrl","headline").params({"first-name":firstName,"last-name":lastName,"sort": "distance"}).result(showResults);
      }

   function showResults(result) {
    $("#informationContainer").html('');
            $("#informationContainer").append("<span>Click a link to the left to list possible LinkedIn matches.  The one you want is most likely on top.</span>");
        for (var index in result.people.values) {
         var profHTML = "";
            profile = result.people.values[index]
            if (profile.pictureUrl) {
                profHTML += "<p><a target="_blank" href="" + profile.publicProfileUrl + "">";
                profHTML += "<img class=img_border height=30 align="left" src="" + profile.pictureUrl + "">"; 
                profHTML += "" + profile.firstName + " " + profile.lastName + " - " +  profile.headline +  "</a>";  
            }
            $("#informationContainer").append(profHTML);
        }     
   }
   
   
   function showUser(result) {
    alert(result);
   }
   
   
   $(document).ready(function(){
       // twitter api's base url
     var jsonUrl="http://winaspectreapi.appspot.com/api/sessions";
     //alert("jquery works");
     
    // alert(document.domain);
     
        
   });
   
   function listNames(data) {
       for(i=0;i < data.length; i++) {
        names = data[i].author.split(" ");
        var output = '<div id="lineItem">Speaker:  <a href="#'' + names[0] + ''" onclick="getLinkedInfo('' + names[0] + '','' + names[names.length - 1] + ''); return false;">' + data[i].author + '</a><br/>';
        output = output +  'Title:  ' + data[i].title + '<hr/></div>';
         $("#feedList").append(output);
       }
    
   }
   
   
   function alertResponse(data, status) {
        //alert("data: " + data + ", status: " + status);
         if($.isArray(data)) {
          listNames(data);
         }
      }
   
   //not being used because apparently JSON is not valid
   function buildListAJAX(jsonUrl) {
    // alert(jsonUrl);
     $.ajax({
         url: jsonUrl,
         dataType: 'jsonp',
         jsonpCallback: 'alertResponse'
     });
      
   }
   
   
   

 
   
  </script>
 </head>
 <body>
  <div id="mustLogin">
   <h2>You must login Facebook using the button below to use this CodePaLOUsa application.</h2>
    <script type="IN/Login" data-onAuth="loadData"></script> 
   </div>
  
  <div id="container">
   <div id="feedList">
              
   </div>
   <div id="informationContainer">
         Click a link to the left to list possible LinkedIn matches.  The one you want is most likely on top.    
   </div>   
  </div>
 </body>
</html>

Less Is More ~ Older posts are available in the archive.