Posting JSON-formatted data

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.

How to do it...

Look at the project post_form for the code.

  1. Our form (refer the next diagram) will post data for a job in IT; we reuse the class 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
    }
  2. The model class is made available to the code in post_form.dart using the following code:
    import '../model/job.dart';
  3. We add our own event handler for the submit button using the following code:
    void main() {
      querySelector("#submit").onClick.listen(submitForm);
    }
  4. The method 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
    }
  5. The _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();
    }
  6. The 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:

How to do it...

The client sends job data

In the previous screenshot, no server is shown because there is no web server to process the request.

How it works...

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.

See also

  • See the Working with blobs recipe in Chapter 6, Working with Files and Streams, to learn how to make a request to download a blob file
..................Content has been hidden....................

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