This is a recipe for a client web app that sends a request to a web server. The request contains the form's data that is posted in the JSON format.
Look at the project post_form
for the code.
Job
in the Making toJSON and fromJSON methods in your class recipe from Chapter 4, Object Orientation. We keep the example short and simple, but add two new properties, posted
and open
. Have a look at the following code:class Job { String type; int salary; String company; DateTime posted; // date of publication of job bool open = true; // is job still vacant ? Job(this.type, this.salary, this.company, this.posted); // toJSON and fromJSON methods }
model
class is made available to the code in post_form.dart
using the following code:import '../model/job.dart';
void main() { querySelector("#submit").onClick.listen(submitForm); }
submitForm
makes and sends the request as follows:submitForm(e) { e.preventDefault(); // Don't do the default submit. // send data to web server: req = new HttpRequest(); req.onReadyStateChange.listen(onResponse); // POST the data to the server. var url = 'http://127.0.0.1:PORT'; req.open('POST', url); req.send(_jobData()); // send JSON String to server }
_jobData
function prepares the data to send as follows:_jobData() { // read out data: InputElementicomp, isal, iposted, iopen; SelectElementitype; icomp = querySelector("#comp"); itype = querySelector("#type"); isal = querySelector("#sal"); iposted = querySelector("#posted"); iopen = querySelector("#open"); var comp = icomp.value; var type = itype.value; varsal = isal.value.trim(); var posted = DateTime.parse(iposted.value.trim()); var open = iopen.value; // make Job object Job jb = new Job(type, int.parse(sal), comp, posted); // JSON encode object: return jb.toJson(); }
onResponse
function gets the response from the server and shows it on the screen as shown in the following code:void onResponse(_) { if (req.readyState == HttpRequest.DONE) { if (req.status == 200) { serverResponse = 'Server: ' + req.responseText; } } else if (req.status == 0) { // Status is 0: most likely the server isn't running. serverResponse = 'No server'; } querySelector("#resp").text = serverResponse; }
The following screenshot shows how our screen looks after sending the data:
In the previous screenshot, no server is shown because there is no web server to process the request.
In step 1, we added a DateTime
property. Such a type is not natively serializable to JSON; the encode
method does not know how to handle this case. We have to define this ourselves and provide a toEncodable
closure as the second optional argument of JSON.encode
; this returns an appropriate serialization of DateTime
. The following code is the revised toJson
method in the class Job
:
String toJson() { var jsm = new Map<String, Object>(); jsm["type"] = type; jsm["salary"] = salary; jsm["company"] = company; jsm["posted"] = JSON.encode(posted, toEncodable: (p){ if(p is DateTime) return p.toIso8601String(); return p; }); jsm["open"] = open; var jss = JSON.encode(jsm); return jss; }
The important part happens in step 4, where the HttpRequest
object is sent; req.open
posts the data to the URL of the server (here we test it locally with the localhost address 127.0.0.1). We also define a callback function onResponse
for the onReadyStateChange
event that signals when a server response comes in.
The send()
function happens asynchronously, so it returns as soon as the request is sent; req.send
takes the data to be sent as the argument, and this is the JSON string prepared in the function _jobData
in step 5. This reads out the data values from the screen and makes a Job
object with them, and JSON formats that object with toJson
.
Finally in step 6, when the request is complete and the server responds with the OK status 200, which means success, the text response from the server is shown; otherwise it shows No server. The state in which the communication with the server is carried, is given by the readyState
field. The ready state can have five possible values: unsent
, opened
, headers received
, loading
, and done
. When the ready state changes, HttpRequest
fires an event named onReadyStateChange
and the onResponse
callback function gets called.