JSONP With Only Native JavaScript – Part I

JSON

JavaScript LogoMost front-end developers consume JSON at some point. It has become commonplace nowadays to fetch data from a cross-domain site and present that data in your page. JSON is lightweight, easy to consume and one of the best things to come along in a while.

Another one of the best things to come along has been this:

jQuery.getJSON()

jQuery makes fetching JSON trivial. And there ain’t nothin’ wrong with that. But it’s not a bad idea to have a solid understanding of exactly what is going on under the hood.

The big advantage of JSONP is that it allows data to be retrieved from any URL on the planet with no concern for the kind of cross-domain limitations of AJAX. So this means that we are taking advantage of one of the older features of the JavaScript language: the ability to inject a remote script into our page. In a nutshell, JSONP is accomplished via dynamic script injection. In other words, you create a script tag, set the ‘src’ attribute to be any script you like, and that script calls a function in your page, passing it some data.

Now in the real world, your remote script would likely be produced by an API that supports JSONP. In these cases you have probably seen the URL of JSONP call look something like this:

http://www.somedomain.com?callback=

This is a more sophisticated approach and will be covered in Part II. For now, however, we will keep things very simple. In order to do so, we have to have an agreement between our JSON file and our web page. Our web page has a function expression that makes that function available, and the JSON file knows to call that function.

First, let’s take a look at our JSON file.

Example # 1

Example # 1 is our JSON file. It is really just a JavaScript file. It consists of one function call: jsonpCallback(). The sole argument to this function call is an array of objects. Each object has two properties: ‘name’ and ‘accountNumber’.

We’ll come back to this file shortly. For now, it’s just important to focus on the fact that this is simply a JavaScript file that makes a function call, and passes an array to that function.

Example # 2

In Example # 2, we have the markup for our web page. Now there are two things happening here:

1) The function declaration jsonpCallback() might look familiar to you. This is the function that is called from our JavaScript file ‘data.js’. Notice that this function takes one argument: ‘data’. So it expects to receive some data. Inside the function we assume that the data came through and we inspect it in the console.

2) After the function declaration, we dynamically append a script to the head of the document. Now if you take a close look at the ‘src’ attribute of our script, you’ll see that it is ‘data.js’

Putting the pieces together

Now that we have the details laid out, let’s walk through the sequence of events:

  1. The page loads, and the function declaration for jsonpCallback() is evaluated
  2. jsonpCallback() now exists and can be called
  3. We dynamically append a script tag to the page
  4. The URL for this new script tag is data.js
  5. data.js is loaded and the code inside of it executed
  6. data.js calls the function jsonpCallback(), and passes it the array of data
  7. jsonpCallback() receives the data passed to it and we inspect it in the console

Again, this is an extremely rudimentary example. The focus here was to illustrate the core concepts in play: dynamic script injection and passing data to a function. In Part II, we will look at a more dynamic approach to JSONP.

Here is a link to the working example for this argument: http://examples.kevinchisholm.com/javascript/jsonp/example-1/

Summary

In this article we learned how to implement JSONP using only native JavaScript. We discussed how the script that we dynamically inject into the page calls a function, passing data into the function that it calls.

Helpful Links for JSONP

http://en.wikipedia.org/wiki/JSONP

http://json-p.org/

http://remysharp.com/2007/10/08/what-is-jsonp/

Cross-Browser Asynchronous JavaScript Script Loading

Asynchronous

JavaScript LogoWhile it is perfectly normal to have one or more JavaScript tags in your markup as prerequisites to your code, there may be situations in which you want to avoid this

When I build a piece of functionality that is contained in one JavaScript file, I try to avoid asking the back-end developer to include additional scripts in the markup. So, my philosophy is: my script provides a certain “chunk” of functionality. Whatever external resources my script depends on are my script’s problem and will be handled accordingly. As often as possible, I’d like the consumer to simply choose to use or not use my script. This decision should involve simply adding or removing my script from the markup. The remaining abstraction is my responsibility.

This may seem a bit altruistic, but so far I’ve never had to lower my standards on the issue. The key to keeping this philosophy is, of course, the ability to reliably load other scripts asynchronously. I say “reliably” because it’s not enough to simply inject the script into the head of the document. You need to know when that script has successfully loaded before you take further actions that depend on the script.

The good news is: modern browsers provide the “onload” event, allowing you to set up your handler without too much effort. But the bad new is: Microsoft’s Internet Explorer 8 and below do not implement that event. So, there is some work to do. It’s not too bad; it just means we need to fork our code a bit.

Oh, and by the way; you might be wondering why I didn’t simply use the jQuery.getScript() method. jQuery is awesome and we all love it more than coconut ice cream. But I strongly believe that it’s important to know how to do these things with native JavaScript. One day a client will tell you that for whatever reason, you can’t use jQuery. When that day comes, you’ll be ready.

So let’s have at it!

Example # 1

Now here in Example # 1, we’ve created a function that takes a URL and a callback as arguments. The URL is required, the callback is optional. As you can see, this is pretty straightforward stuff:

  1. Create a script DOM element
  2. Assign an anonymous function to the “onload” event
  3. Set the script’s source
  4. Inject the script into the DOM

No worries.

Example # 2

In Example # 2 we have rolled up our pant legs and stepped into the cold wet mud that is Internet Explorer 8 (and below). So here we will need to assign that same anonymous function to the script element’s “onreadystatechange” property. And this property will change as the “ready state” of the script element updates. When that ready state is “loaded”, then we can be confident that the external script has successfully loaded and executed. It’s a bit more work, but then again, Internet Explorer wouldn’t be such a charming little browser if it adhered to the same kind of common-sense standards as every other modern browser on the planet… but I digress.

Example # 3

Well… Example # 3 certainly contains a bit more code, huh? In fairness, it’s heavily commented. But outside of that, what has happened is that as promised, we’ve forked the code so that we can support good ol’ IE, as well as all the other browsers that are made by sane people. I chose to check for the existence of document.attachEvent as a way of sniffing the browser. Some may disagree, but for me, it has always worked just fine.

If you follow the link to the full working example below, be sure to open your JavaScript console. When you do, you’ll see that the message from the actual external script always fires before the callback. Always. This is what we needed: the ability to load the script, and reliably know when it has loaded so that we can safely assume whatever resources it provides are available to us. So go ahead and try it in Internet Explorer 8 or Internet Explorer 7; it works just fine.

The full working example can be found here: http://examples.kevinchisholm.com/javascript/script-loading/

Summary

In this article, we learned how to implement a reliable solution for cross-browser asynchronous JavaScript loading. We discussed the need to fork our code in order to support Internet Explorer 8 (and below), and the “onreadystatechange” event that it implements.

Helpful Links for JavaScript loading

http://css-tricks.com/thinking-async/

http://friendlybit.com/js/lazy-loading-asyncronous-javascript/

Complex Multiple Script Loading Using the jQuery.when() Method and the jQuery.Deferred Object — Part II

jQuery

jQuery LogoWhat happens when your JavaScript code depends on not only multiple asynchronous scripts, but also one or more JSONP calls? Once again, jQuery.Deferred() and jQuery.when() save the day.

In Part I of this article: “Complex Multiple Script Loading Using the jQuery.when() Method and the jQuery.Deferred Object Part I“, we discussed the complex nature of multiple asynchronous dependencies. In that article, we were able to count on jQuery.when() to pay attention to the resolution of our jQuery.Deferred objects. In this second part, we’ll complicate things even further by adding a JSONP dependency. The “complication” is the fact that the success of the JSONP call requires us to re-think how we will leverage our jQuery.Deferred object’s resolution.

In my opinion, the asynchronous script calls are fairly easy to manage:

But what about a JSONP call? How do we squeeze that scenario into the jQuery.Deferred / jQuery.when() paradigm?

The approach I have taken starts with a variable that is set to an unresolved jQuery.Deferred object. As soon as you create this variable, you can then program around it. In the true spirit of JSONP, you can name your callback whatever you want. If the server supports JSONP, then you can assume that it will call your callback, passing in the much-desired return data.

Here is a pseudo-code walk-through:

Example # 1

In Example # 1, we have the core code that makes this all work. The interesting thing is that the actual JSONP call comes last. What we do beforehand is set up the tools we need to handle this asynchronous event. What makes this scenario a bit special is that you manually resolve the jQuery.Deferred object in the JSONP callback: “foo.resolve()”. This very nicely kicks in the .when() method that is chained to the return value of the jQuery.when() call.

Example # 2

In Example # 2, we have the code for the full working example. It builds upon the full working example from Part I of this article, but the added functionality has no connection to the form validation. The point that is (hopefully) being made here is:

  • This code provides a way to ensure that multiple asynchronously loaded dependencies are loaded before further action is taken.
  • This code checks to see if any of the asynchronously loaded dependencies have already been loaded in the page (possibly by hard-coded synchronous calls or another script).
  • This code allows for the inclusion of an asynchronously loaded JSONP dependency.

Going through the code line-by-line would be repetitive as that was already done in Part I. What might be helpful is to look at the code and see where the approach taken in Example # 1 has been worked into the full working code (Example # 2).

Here is the URL for the full working example: http://examples.kevinchisholm.com/jquery/deferred-and-when/complex-multi-async-dependencies.html

Summary

In this article we learned how to accommodate a JSONP call as an asynchronous dependency. We leveraged the jQuery.Deferred object and the jQuery.when() method to manage and act upon the resolution of the JSONP call.

Complex Multiple Script Loading Using the jQuery.when() Method and the jQuery.Deferred Object Part I

jQuery

jQuery LogoThe jQuery.when() method allows you to treat multiple asynchronous script calls as one logical event. But what if there is a chance that one or more dependencies are already loaded?

I just completed a project for a client that involved some tricky script loading logic. I had to use a jQuery plugin and icanhaz.js for templating (I prefer Mustache.js, but the previous developer had implemented icanhaz.js in many of the site’s templates). Now the difficult thing was that I had already written some JavaScript code that lazy-loads touts in the main navigation bar, which appears on every page in the site. So, the situation in hand was as follows:

  • My JavaScript depends on icanhaz.js and a jQuery plugin
  • icanhaz.js is asynchronously loaded further up the page
  • Since icanhaz.js is loaded asynchronously, I can’t assume it’s loaded when my new code runs
  • I don’t want to load icanhaz.js twice

eeesh….

I knew I could count on the jQuery.when() method to handle the multiple asynchronous script loads. Specifically, jQuery.when() can treat two or more asynchronous script load events as one event. The completion of the multiple events can represent one completed event, which can be used to tell the rest of your code: “hey, we have what we need, let’s proceed.” But at first I was not sure how to abstract the details of whether or not a script is already loaded. For example, If icanhaz.js has already been loaded in the page, I don’t want to waste time by loading it again (and potentially cause unexpected behavior because it loaded twice).

So I decided to leverage the jQuery.deferred constructor.

In short, for each script that needed to be loaded (i.e. each dependency), I wrote a function that checks to see if that script was already loaded. If so, then the function returns a resolved jQuery.deferred instance. If not, then I simply use the jQuery.when() method to wrap a jQuery.getScript() call, which returns an unresolved jQuery.deferred instance. So either way, my function returns a jQuery.deferred instance. This is perfect because jQuery can easily understand (and act upon) the “state” of a jQuery.deferred instance. And most importantly, jQuery can view multiple jQuery.deferred instances as one “event”.

“…..hmmmm Idunno Kevin, this is all starting to sound a little convoluted to me!”

I had similar feelings when I was working this out in my head. But once I fired up my JavaScript console, and started testing the code, it was not only easy to understand the logic, it worked flawlessly (serious kudos to the jQuery folks; these are awesome features).

So, for this article, I decided to use Mustache.js and the jQuery validation plugin as my dependencies. Mustache.js will be used to build the form and the jQuery validation plugin will provide form validation.

Example # 1

In Example # 1, we simply have the markup for the page. Not too much going on here: a page wrapper and two header elements. What it does illustrate is that the form and the validation you see when you run the final working example is all handled by our two dependencies: Mustache.js and the jQuery form validation plugin.

Example # 2

Now, in Example # 2, we have provided two constants which are simply the URLs for the script calls that we (might) have to make. This is a pattern that I like to follow, which can help to minimize clutter in your implementation code; make values that will never change constants and put them all in one coherent place.

The variable “data” simply holds an object literal that will be used by Mustache.js to populate the template, and the variable “template” is the string used by Mustache.js to create the template. (Notice the values inside of the double curly brackets: “{{}}”; these all map to properties in the “data” object.)

Example # 3

In Example # 3, we have a function that always returns a jQuery.deferred instance. The if/else statement provides two possible outcomes: Mustache.js is already loaded in the page or Mustache.js is not loaded. We test for the existence of window.Mustache (and the value of its “name” property) in order to determine the answer. If Mustache.js is already loaded, then we simply return a resolved jQuery.deferred object. If it is not, we then return a call to jQuery.when(), passing a jQuery.getScript() call as an argument. The jQuery.when method returns a jQuery.deferred instance that is in an “unresolved” state until the getScript() call completes.

The key point here is that even though in this case our function returns an un-resolved jQuery.deferred instance, the fact that it is a jQuery.deferred object is all we need.

So there is no need to walk through the function that does the same thing for the jQuery validation plugin; the logic is exactly the same. If you look at the code for the full working example at the end of this article, you’ll see that the only difference is the URL for the script that is loaded, and the way in which we determine if the plugin exists (i.e. we check for the existence of a property of the jQuery.prototype object named “formval”).

Example # 4

Now here in Example # 4, we create two variables. Both variables become a jQuery.deferred object because in each case, the variable is being set to the return value of the methods we just discussed in Example # 3: each of these methods returns a jQuery.deferred object. Again, these objects are in either a “pending” or “resolved” state, depending on whether or not the specified script was loaded.

Example # 5

{ //build the markup fom the template (uses Mustache.js) var form = Mustache.render(template,data); //inject the form $(‘#container’).append(form); //setup the form for validation (form validation plugin) $(‘#testform’).formval(); });

In Example # 5, look very closely at the first line: $.when(formValIsLoaded,mustacheIsLoaded). Essentially, this line says: “When the two arguments resolve…” that is, when both of these argument’s “state” changes to “resolved”. Now this is important because it’s treating the resolution of two or more events as one event. For example:

Event-A.completed + Event-B.completed = Event-C.done

So, this $.when() method will return when all of the arguments have a “resolved” state. Since the return value is also a jQuery.deferred object, then we can utilize its .done() method. We pass an anonymous function as an argument to the .when() method. This function will execute when all of the arguments of the .when() method are resolved.

Once we are inside of the anonymous function, we can be confident that our dependencies are loaded. At this point, there are just a couple of things left to do:

  • Create our form, using the Mustache.render() method, and inject it into the DOM
  • Set up validation using the jQuery.validation plugin

So, here we have it, the end result of all this work we have done, which is a simple one-field form. When you view the full working example (see link below), you can click the submit button to see the validation fail, which will cause the error message to show. And the label for the name field, the submit button’s text and the error message have all been supplied by the “data” variable in our code, which if you remember, is an object literal that contained all of those string values.

Example # 6

In Example # 6, we have the full code for our working example.

Here is the JsFiddle.net link for our full working example: http://jsfiddle.net/Ebj4v/5/

Final Proof of Concept

In the links that follow, we have added script tags to the code. In the first two cases, one of our dependencies is pre-loaded. In the third case both are pre-loaded. Chrome does not like the mimetype of the scripts as they are served from github.com, so please view these examples in FireFox. Open up your JavaScript console when viewing the examples. In each case, you will see a message indicating which dependency was pre-loaded. In all three cases, the resulting behaviour is the same: our code checks to see if a dependency is loaded, if so, great, and if not it loads it.

Mustache.js preloaded: http://jsfiddle.net/Ebj4v/6/

jQuery.validation plugin preloaded: http://jsfiddle.net/Ebj4v/7/

Both Mustache.js and jQuery.validation plugin preloaded: http://jsfiddle.net/Ebj4v/8/

Summary

In this article we learned how to solve a complex script-loading scenario. In doing so, we discussed the jQuery.deferred() constructor and jQuery.when() methods, learning how they can be leveraged to create an if/else logic so that we can determine whether or not a script was loaded, and then depending on the answer, take the appropriate action.

Helpful Links for jQuery.deferred and jQuery.when

jQuery.deferred

http://api.jquery.com/jQuery.Deferred/

http://api.jquery.com/category/deferred-object/

http://blog.kevinchisholm.com/javascript/jquery/using-the-jquery-promise-interface-to-avoid-the-ajax-pyramid-of-doom/

jQuery.when

http://api.jquery.com/jQuery.when/

Book Review: Instant Dependency Management with RequireJS How-to

Asynchronous Module Definition
Instant Dependency Management with RequireJS How-to
Instant Dependency Management with RequireJS How-to from Packt Publishing

Greg Franko’s book, Instant Dependency Management with RequireJS How-to, from Packt Publishing, strives to cut through the clutter and introduce you to AMD through Require.js

Asynchronous Module Definition is a term that can be intimidating. Even worse, it can potentially discourage JavaScript programmers from learning about and implementing the AMD API.  Fortunately, this book can be helpful.

The initial areas of discussion. are what you might expect: learning how to load Require.js both synchronously and asynchronously, as well as setting Require.js configuration values. But what becomes apparent is that implementing AMD patterns does not mean having to abandon the tools you use. Mr. Franko does a nice job of illustrating how jQuery can be exposed in your pages as an AMD module, as well as Jasmine unit tests and client-side JavaScript templating. All of this is accomplished by leveraging Require.js. A logical extension of this journey is a discussion of JavaScript libraries that do not expose themselves as AMD modules such as Backbone.js and jQueryUI Widget Factory. In these cases, a thorough explanation details how to work around this challenge, and keep tight control of your JavaScript resources. There is also helpful content here for mobile web developers.

Instant Dependency Management with RequireJS How-to may not be the definitive “go-to” resource for those who are completely new to the concept of AMD or Require.js. While key concepts are well served, this book’s strength is its ability to broaden one’s perspective with regards to what Require.js is capable of. By illustrating jQuery’s ability to be exposed as an AMD module, the power and flexibility of Require.js becomes increasingly apparent.

I would recommend this book for JavaScript developers who are already familiar with the concept of asynchronous module definition and understand in general how Require.js works. For this audience, Mr Franko’s direction will deliver a great deal of value with regards to the numerous architectural solutions that are detailed. In each case it is easy to see that Reqiure.js is more than simply a sophisticated script loader. This library exposes a number of properties and methods that help you to leverage AMD as broadly as possible, even when some of the libraries in use are not AMD compliant.

Instant Dependency Management with RequireJS How-to is available in paperback, or eBook format.

  • Author: Greg Franko
  • File Size: 100 KB
  • Print Length: 42 pages
  • Publisher: Packt Publishing
  • Publish Date: May 22, 2013
  • Language: English
  • ASIN: B00CXRTC1Q