Ajax in Dart

We start our Dart application by loading a couple of Dart libraries with a main function in scripts/comics.dart.

your_first_dart_app/web/scripts/skel.dart
 
import​ ​'dart:html'​;
 
import​ ​'dart:convert'​;
 
main() {
 
// Do stuff here
 
}

As you’ll see in Chapter 10, Libraries, there is a lot of power in those import statements. For now, we can simply think of them as a means for pulling in functionality outside of the core Dart behavior.

All Dart applications use main as the entry point for execution. Simply writing code and expecting it to run, as we do in JavaScript, will not work here. It might seem C-like at first, but does it honestly make sense that code lines strewn across any number of source files and HTML will all start executing immediately? The main entry point is more than convention; it is a best practice enforced by the language.

As for the contents of the main function, we take it piece by piece. We are retrieving a list of comic books in our collection and using that to populate an element on our page.

We need to identify the DOM element to which the list will attach (#comics-list). Next we need an Ajax call to fill in that DOM element. To accomplish both of those things, our first bit of Dart code might look like the following:

your_first_dart_app/web/scripts/comics.dart
 
main() {
 
var​ list_el = document.query(​'#comics-list'​);
 
var​ req = ​new​ HttpRequest();
 
}

Aside from the obvious omission of the function keyword, this example might be JavaScript code! We will cover more differences in Chapter 3, Functional Programming in Dart. Still in Dart are the semicolons and curly braces that we know and love—the language designers have certainly made the language at least superficially familiar.

Recipe 2Note: Unlike in JavaScript, semicolons are not optional in Dart.

In addition to being familiar, this code is easy to read and understand at a glance. There are no weird, legacy DOM methods. We use document.query() for an element rather than document.findByElementId(). And we use the familiar CSS selector of #comics-list, just as we have grown accustomed to in jQuery.

Also note that we are not creating an XMLHttpRequest object. In Dart, it is just HttpRequest. This may seem a trivial change, but remember Dart is written for today’s Web, not to support the legacy of the Web. And when was the last time anyone sent XML over web services?

Recipe 3 Note: Depending on the version of Dart, the code editor, or tools that you are using, you may see warnings that query is deprecated. It is not deprecated. Well, not really. The current version is deprecated, but a new query that behaves nearly identically but tracks newer DOM standards will replace it as soon as the current version is removed. This books opts to future-proof itself by using the current query, which will work just fine when the new and improved version rolls along. If you really dislike these warnings, feel free to replace instances of query with querySelector and to replace queryAll with querySelectorAll. The code examples will continue to work just fine.

So far we have the UL that we want to populate and an HttpRequest object to do so. Let’s make the request and, after a successful response, populate that UL. As in JavaScript, we open the request to the appropriate resource (/comics), listen for an event that fires when the request loads, and finally send the request.

 
main() {
 
var​ list_el = document.query(​'#comics-list'​);
 
var​ req = ​new​ HttpRequest();
 
req.open(​'get'​, ​'/comics'​);
 
req.onLoad.listen((req) {
 
var​ list = JSON.decode(req.target.responseText);
 
list_el.innerHtml = graphic_novels_template(list);
 
});
 
req.send();
 
}

Most of that code should be immediately familiar to anyone who has done Ajax coding in the past. We open by creating an XHR object and close by specifying the resource to be retrieved and actually sending the request.

It is when we add event handlers that we see a more fundamental departure from the JavaScript way. The XHR object (er, HR object?) has an onLoad property. The onLoad property is a stream. Streams are used everywhere in Dart (server-side, client-side, everywhere) as a means of allowing code to receive data without blocking any other code from executing. In this case, the UI should remain responsive until the data from the HttpRequest is available, at which point we do something with it.

In this case, we parse (well, “decode” in Dart) the supplied JSON into a list of hashes, which might look like this:

your_first_dart_app/comics.json
 
[
 
{"title":​"Watchmen"​,
 
"author":​"Alan Moore"​,
 
"id":1},
 
{"title":​"V for Vendetta"​,
 
"author":​"Alan Moore"​,
 
"id":2},
 
{"title":​"Sandman"​,
 
"author":​"Neil Gaiman"​,
 
"id":3}
 
]

With that, we hit the final piece of our simple Dart application—a template for populating the list of comic books.

 
graphic_novels_template(list) {
 
var​ html = ​''​;
 
list.forEach((graphic_novel) {
 
html += graphic_novel_template(graphic_novel);
 
});
 
return​ html;
 
}
 
graphic_novel_template(graphic_novel) {
 
return​ ​'''
 
<li id="${graphic_novel['​id​']}">
 
${graphic_novel['​title​']}
 
<a href="#" class="delete">[delete]</a>
 
</li>'''​;
 
}

The first function simply iterates over our list of comic books (internally, we hipsters think of them as graphic novels), building up an HTML string.

The second function demonstrates two other Dart features: multiline strings and string interpolation. Multiline strings are identified by three quotes (single or double). Inside the string, we can interpolate values (or even simple expressions) with a dollar sign. For simple variable interpolation, curly braces are optional: $name is the same as ${name}. For more complex interpolation, such as hash lookup, the curly braces are required.

And that’s it! We have a fully functional, Ajax-powered web application ready to roll. The assembled code is as follows:

 
import​ ​'dart:html'​;
 
import​ ​'dart:convert'​;
 
main() {
 
var​ list_el = document.query(​'#comics-list'​);
 
var​ req = ​new​ HttpRequest();
 
req.open(​'get'​, ​'/comics'​);
 
req.onLoad.listen((req) {
 
var​ list = JSON.decode(req.target.responseText);
 
list_el.innerHtml = graphic_novels_template(list);
 
});
 
req.send();
 
}
 
graphic_novels_template(list) {
 
var​ html = ​''​;
 
list.forEach((graphic_novel) {
 
html += graphic_novel_template(graphic_novel);
 
});
 
return​ html;
 
}
 
graphic_novel_template(graphic_novel) {
 
return​ ​'''
 
<li id="${graphic_novel['​id​']}">
 
${graphic_novel['​title​']}
 
<a href="#" class="delete">[delete]</a>
 
</li>'''​;
 
}

And loading the page looks like this:

images/your_first_dart_app/dart_comics.png

That is a darned nice start in our exploration of Dart. To be sure, we glossed over a lot of what makes Dart a great language. But in doing so, we have ourselves a very good start on an Ajax-powered web application. Best of all, none of the code that we wrote seemed all that different from JavaScript. Some of the syntax is a little cleaner than what we are used to in JavaScript (no one is going to complain about cleaner code), and those strings are quite nice. But, all in all, it is safe to say that we can be productive with Dart in relatively short order.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.223.172.132