Last night, I came oh-so-close to getting XHR requests from a Dart web page working. To be precise, I was able to get HTTP GET requests to flow via XHR, but POSTs eluded me. Tonight, I pick back up, starting with some tips passed along by Adam Coding in last night's comments.
The first thing that I try is setting the request headers. I do not think that this will help as the error that I am getting is that
send()
is not implemented, but fingers crossed. In yesterday's comic book application, I now specify that I am passing application/json
: var data = {'title':title.value, 'author':author.value}
, json = JSON.stringify(data);
print(json);
var req = new XMLHttpRequest();
req.open('post', '/comics', true);
req.setRequestHeader('Content-type', 'application/json');
req.send(json);
print(req.responseText);
Unfortunately, but not too surprisingly, I am still greeted with a not-implemented exception when I trigger the XHR send by submitting the form:Exception: NotImplementedException Stack Trace: 0. Function: 'XMLHttpRequestImplementation.send' url: '/home/cstrom/repos/dartium/src/out/Release/obj/gen/webkit/bindings/XMLHttpRequestImplementation.dart' line:43 col:3 1. Function: 'XMLHttpRequestWrappingImplementation.send' url: 'dart:htmlimpl' line:25561 col:20 2. Function: '::function' url: 'http://localhost:3000/scripts/comic_put.dart' line:27 col:13 3. Function: 'EventListenerListImplementation.function' url: 'dart:htmlimpl' line:23183 col:35Bummer.
My next step is to try this from the command-line version of Dart that I have. I reduce my browser script to the following:
#import('dom'); #import('dart:json'); main() { var data = { 'title':"Watchmen", 'author':"Alan Moore" } , json = JSON.stringify(data); print(json); var req = new XMLHttpRequest(); req.open('post', 'http://localhost:3000/comics', true); req.setRequestHeader('Content-type', 'application/json'); req.send(json); print(req.responseText); }); }Unfortunately, that also fails to work. It seems that the command-line version of Dart lacks the dom, html, and json libaries:
➜ command_line git:(master) ✗ dart xhr01.dart '/home/cstrom/repos/dart-site/examples/command_line/xhr01.dart': Error: line 1 pos 1: library handler failed: Do not know how to load 'dart:html' #import('dart:html'); ^Again bummer.
The last thing that I can try is compiling the Dart code into Javascript:
scripts git:(master) ✗ frogc comic_put.dart /home/cstrom/local/dart-sdk/lib/htmlimpl/htmlimpl.dart:23094:21: warning: a map literal takes one type argument specifying the value type _listenerMap =That warning message is a bit weird, but seems to be ignorable.{}; ^^^^^^ ➜ scripts git:(master) ✗ ls -1 comic_put.dart comic_put.dart.js
After switching my web page to use the compiled Javascript instead of the pure Dart:
<script src="scripts/comic_put.dart.js" type="application/javascript"></script>Then things work. My express.js + node-dirty backend responds with:
{"title":"Watchmen","author":"Alan Moore","id":"12e5c6c33b16399f778bad86fc6bc082"}And, indeed, checking the node-dirty store, my new record is indeed in place:
➜ comix git:(master) ✗ node > db = require('dirty')('comix.db') > db.get('12e5c6c33b16399f778bad86fc6bc082') { title: 'Watchmen', author: 'Alan Moore', id: '12e5c6c33b16399f778bad86fc6bc082' }For the sake of completeness, the POST route in my express.js backend looks like:
app.post('/comics', function(req, res) { var graphic_novel = req.body; graphic_novel['id'] = dirtyUuid(); db.set(graphic_novel['id'], graphic_novel); res.statusCode = 201; res.send(JSON.stringify(graphic_novel)); });And yes, externally they might look like comic books, but I will always think of them internally as graphic novels. ANYhow...
One caveat with the compiled Javascript is that it is not executed on DOM-ready like the equivalent Dart code. With the Dart version, I could put the
<script>
tag before the form HTML. Once I converted to the compiled Javascript, I had to move the <script>
tag after the HTML—otherwise the attempt to add an on-submit event handler failed because the Javascript could not find the form element.I am a bit surprised that the version of Dartium that I have does not support XHR
send()
with a data argument. The frogc
dart-to-javascript compiler is older than Dartium and yet it supports sending data via XHR. I will likely recompile Dartium with the latest source code changes included and follow up on the mailing list in the upcoming days.In the end, a few NotImplemented exceptions are to be expected for such a hipsterish language. If nothing else, it is pretty cool to know that the Dart code that I quickly threw together last night was sufficient to read form values and submit them via XHR. That is a definite win for Dart.
Day #268
No comments:
Post a Comment