Tag Archives: JSON

Simple Twitter Timeline Data

26 Sep 2015

We’re all familiar with how to embed a Twitter timeline – which is to simply copy the Widget code from Twitter and paste into your site. Twitter then drops in an iframe and you have a timeline.

The alternative is to use the twitter API to pull a timeline and then deal with OAUTH.

Or, you could just scrape a timeline out of the GET response that an iframed timeline’s HREF creates which is what I’ve done here. The key to this working at all is that Twitter’s iframe-embedding method creates a GET request that returns a JSONP payload. JSONP allows developers to circumvent cross domain restrictions which is why embedding a timeline works.

Knowing that I can successfully retrieve timeline data and that the data will be sent to a callback of my choosing (the “P” in “JSONP”) all I needed to do was to parse out the useful information – parse it out because the response we get back is not in JSON notation but a string of html. Parsing is a pain though so I decided to use jQuery to convert the string to a DOM object so that I can search for the nodes by traversing the DOM tree for the bits of information that I need.

Updated 4/11/2016 to reflect the latest Twitter changes

Here’s an example, use the timeline ID below or enter your own.

Note that we’re limited to the 20 most recent tweets. I convert everything to an array of tweet objects as illustrated below:

twttr_updated_jsonp

You can get the code here: https://github.com/r-luna/simple_twitter_timeline or simply view this page’s source.

All you need is the ID of the timeline, a callback of your own making, and jQuery to get this to work.

In this example you can see that the function to get your timeline data is namespaced to twtrUtil. To get your timeline call twtrUtil.getTimeline(CALLBACK_HERE,ID_HERE):

    function handleResponse(o){
        console.log(o);
        $('#response').html(JSON.stringify(o));
    }
        
    function getTimeline(){
        var id = $('input[name="id"]').val();
        twtrUtil.getTimeline(handleResponse,id);
    }

Your next thought would be “how do I get a twitter timeline id?”. Its easy to do, just create a widget in your Twitter account, find the public timeline that you want to use, then create the Widget. Once created the Widget ID appears in the URL of the widget create success page. The ID identifies the widget which of course is setup to show the timeline that you selected.

See this example URL which illustrates where to find the ID:

  • https://twitter.com/settings/widgets/646067303877115905/edit?focus_textarea=1&notice=WIDGET_CREATED

Saving Game Data in SCORM

27 Sep 2014

Every once in a while I have to wrap something in SCORM. Its not terribly often but it happens maybe about twice a year. This time around it was a Flash-based training module for a local hospital. Applying the SCORM wrapper has become rather blasé; I apply the wrapper, tell the devs what JS functions to call, tell them how to get data out of the LMS, test and then deploy.

Well, this latest training module contained unique features such as mini-games, related data, and user-selectable items. We needed to be able to save all of this data into the LMS and then retrieve the data and hand it off to the SCO so that not only would it resume from where it left off but that the previous game state would also be reflected within its UI.

The plan here was to convert the data to JSON and then store it in cmi.suspend_data. In SCORM 1.2 the suspend_data element has a maximum capacity of 4,096 characters – plenty for our needs.

Storing the data

My function for receiving the JSON payload from Flash and storing it looked similar to this:

// The data is already stringified within the Flash movie and then passed to this function
function storeSuspendData(str){
     LMSSetValue('cmi.suspend_data',str);
}

Immediately this caused an issue which turns out is due to the double-quotes that are part of JSON formatting. In order to be able to successfully insert JSON into the LMS I had to replace all the double-quotes with some other character. I chose to use an asterisk.

My function then turned into something like this:

// The data is already stringified within the Flash movie and then passed to this function
function storeSuspendData(str){
    LMSSetValue('cmi.suspend_data',str.replace(/\"/g,'*'));
}

Here’s some sample JSON:

{"icon":"car","color":"red",{"quizzes":[{"quiz":1,"score":75},{"quiz":2,"score":85},{"quiz":3,"score":95}]}}

And here’s the psuedo-JSON after the search and replace:

{*icon*:*car*,*color*:*red*,{*quizzes*:[{*quiz*:1,*score*:75},{*quiz*:2,*score*:85},{*quiz*:3,*score*:95}]}}

This allowed me to store the data within cmi.suspend_data without issue.

Retrieving the data

Somewhere in all of this an extra set of double quotes were added to the JSON – to the beginning and to the end of the string so that in reality the psuedo-JSON looked like this in the LMS:

*{*icon*:*car*,*color*:*red*,{*quizzes*:[{*quiz*:1,*score*:75},{*quiz*:2,*score*:85},{*quiz*:3,*score*:95}]}}*

My function to get the data out of the LMS at first didn’t account for the beginning and trailing asterisk:

function getSuspendData(str){
    var val = LMSGetValue('cmi.suspend_data').replace(/\*/g,'"");
    return val;
}

Which gave me some bad JSON (note the leading and trailing double-quotes):

"{"icon":"car","color":"red",{"quizzes":[{"quiz":1,"score":75},{"quiz":2,"score":85},{"quiz":3,"score":95}]}}"

So I had to clean that up:

function getSuspendData(str){
    var val = LMSGetValue('cmi.suspend_data').replace(/\*/g,'"');
    val = val.substr(1,val.length);
    val = val.substr(0,val.length - 1);
    return val;
}

When I ran a JSON.parse on my now valid JSON and logged it to the console I could see a bonafide JS object.

Passing the JSON to Flash

The next step was to provide the JSON to flash and we decided to use FlashVars but that came with a problem. Flash vars is simply HTML and HTML attributes use double-quotes. In the sample below you can see the problem right away when the HTML for the Flash object was written to the page:

<param name="FlashVars" value="gameData="{"icon":"car","color":"red",{"quizes":[{"quiz":1,"score":75},{"quiz":2,"score":85},{"quiz":3,"score":95}]}}"" />

Obviously JSON’s double quotes are breaking the HTML. The solution was to not do the search/replace of the previous asterisks – I changed things so that Flash would receive the pusedo-JSON via the FlashVar which meant that the string clean-up would have to happen within Flash.

My updated “get” function looked similar to this:

function getSuspendData(str){
    var val = LMSGetValue('cmi.suspend_data');
    val = val.substr(1,val.length);
    val = val.substr(0,val.length - 1);
    return val;
}

And the FlashVar became valid HTML:

<param name="FlashVars" value="gameData=*{*icon*:*car*,*color*:*red*,{*quizes*:[{*quiz*:1,*score*:75},{*quiz*:2,*score*:85},{*quiz*:3,*score*:95}]}}*" />

And then finally in Flash I simply did the search and replace on the asterisk back to double-quotes and then did a JSON.parse to transform the string into a useful object.

Convert XML to JSON

27 Nov 2012

Having a library of scripts in your back pocket comes in handy – this one is a gem IMO, it is an XML to JSON converter written in JavaScript. I spent the better part of my day trying the wide variety of scripts that a simple Google search yielded. Some didn’t work, others did albeit with quirks (i.e., output that was “technically” JSON while having a less than desired structure).

After much searching and testing I’ve found one that is “perfect”; inserting null values where needed, arrays appearing where they should, extra objects weren’t inserted, etc, etc…. in addition the author shared his test scripts to show the robustness of his work. Download it from here:

http://michael.hinnerup.net

The library claims to also convert JSON to XML – I’ve not tried it but if the quality of the XML to JSON portion is any indication then I expect it should work just as well.

Update 1/2/2013

Michael appears to have updated his blog as all of the content has vanished – and so as a service to others (and myself) I’m providing a link to the js. Whenever Michael gets his blog backup I’ll revert to linking to him, in the meantime you can download the library here:

xml_to_json.js

Also, as his documentation has also disappeared I’ve added a quick example below showing how to request an XML resource via JQuery and turn it into JSON once its been received by the client:

...
function getXML(){
  $.ajax({
    url:      hostURL,
    type:     'GET',
    dataType: 'xml',
    error:function(xhr,status,err){
      // handle errors here
    },
    success:function(responseData,status,xhr){
      if (responseData.childNodes.length > 0){
        var obj = xmlJsonClass.xml2json(responseData); // xml to json conversion happens here
        console.log(obj);
      } else {
        console.log('Response did not appear to contain any children.');
      }
    }
  });
}
...

Tip

I had XML that contained CDATA sections – what the XML-to-JSON script did was create a needless object for the CDATA – a structure that looked like this:

...
{test:
   {test1:'something',
    test2:'something else',
    test3:{#cdata:'another something'}
    }
}
...

Note the value for “test3” – instead of putting the string “another something” as the value the library put in another object. To avoid that, open the xml_2_json.js file and go to line 186 and note the for loop:

...
for (n = xml.firstChild; n; n = n.nextSibling) {
   o["#cdata"] = this.escape(n.nodeValue);
 }
...

That block of code is where the extra object gets inserted – simply change it to this:

...
for (n = xml.firstChild; n; n = n.nextSibling) {
   //o["#cdata"] = this.escape(n.nodeValue); // << original line
   o = this.escape(n.nodeValue); // << new line
 }
...

And now the sample output above appears in a manner that makes more sense:

...
{test:
   {test1:'something',
    test2:'something else',
    test3:'another something'
    }
}
...