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 = {};
^^^^^^
➜ scripts git:(master) ✗ ls -1
comic_put.dart
comic_put.dart.js That warning message is a bit weird, but seems to be ignorable.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