AJAX

AJAX is a technology that allows us to talk to a server directly from JavaScript without reloading the page.

JSONP

JSONP is a hack that allows us to make cross domain requests to a server that doesn't support CORS. It works by injecting a script tag into the page that has the same URL as the site we're trying to access.

To use it, First we must configure our injector to find the JSONP_PROVIDERS. This is a list of injectable dependencies that will let us do JSONP.

document.addEventListener('DOMContentLoaded', function() {
ng.platform.browser.bootstrap(AppComponent, [ng.http.JSONP_PROVIDERS])
});

Now we can inject it into our constructor, like so:

.Class({
constructor: [ng.http.Jsonp, function(jsonp) {
var vm = this;
vm.cats = [];
var url = "http://my-server.com/cats.json?callback=JSONP_CALLBACK"
jsonp.get(url)
.toPromise()
.then(function(response) {
console.log(response.json());
vm.cats = response.json()
})
}]
})

Notice the JSONP_CALLBACK in the url. This is a magic parameter. Angular will do a find and replace for this value in the string, and will add an actual callback fuction which it wil maintain.

Exercise - Flickr

We are going to use the Flickr API to pull a list of images about a tag.

The flickr JSONP endpoint looks like this:

http://api.flickr.com/services/feeds/photos_public.gne?tags=cat&tagmode=any&format=json&jsoncallback=JSONP_CALLBACK

  1. First inject the ng.http.JSONP_PROVIDERS into your global injector. Do this when you bootstrap. See above for how.
  2. Now inject ng.http.Jsonp into your constructor.
  3. In the constructor, make your call, like this: jsonp.get(url)
  4. Store the result in the component. vm.feed = response.json() See above if you don't know where to put this line.
  5. Now in your template, put a line like this: {{feed}}. This will output the JSON feed onto the page.

Extension - List the cats

The JSON feed that comes from the server contains an items attribute, which is an array. Use ngFor to loop over the array

Harder Extension - Allow the user to search for a tag.

The URL has a tag parameter embedded in it. Create a search field with a button. When the user clicks search, trigger a JSONP request that will perform the search.

Harder Exercise - Extract the AJAX into a service

Having AJAX in our component is not so pretty. Better to extract it into a service. We can create a service that will receive injectables using ng.core.Class, like so:

ng.core.Class({
constructor: [ng.http.Jsonp, function(jsonp) {
this.getFeed = function() {
// Do your work here
}
}]
})

Build a class like this, and put your call into it. Have it make the AJAX call for you, and return a Promise. In your component you can call getFeed, and have it return the promise, which you can then chain onto.

comments powered by Disqus