In this related article to the one I wrote on Node.js a couple of months ago, I’ll be demonstrating how we can handle the payload of a POST request in Dart. This assumes that the Content-Type of this payload is application/x-www-form-urlencoded , which essentially describes data that is formatted as a query string.

1. Create our server

Create a main.dart file and enter the snippet below:

import 'dart:io'; void main() async {

var server = await HttpServer.bind('localhost', 9000); await for (HttpRequest req in server) {

req.response

..headers.set('Content-Type', 'text/html')

..write('''

<!doctype html>

<html>

<body>

<form action="/" method="post">

<input type="text" name="fname" /><br />

<input type="number" name="age" /><br />

<input type="file" name="photo" /><br />

<button>Save</button>

</form>

</body>

</html>

''')

..close();

}

}

This bootstraps our server and responds with a form when a request is made to http://localhost:9000 . The snippet begins by importing the dart:io library, since it contains the classes we’ll need to create our server. The whole bootstrapping process happens in a main() function, which is needed to run our Dart app.

To run this file, type the below command in the terminal:

dart main.dart

And you should be greeted with a form in the browser:

Served-up html at http://localhost:9000

2. Capture the POSTed payload

Let’s now ensure that we are dealing with a POST request:

...

... await for (HttpRequest req in server) {

if (req.method == 'POST') {

// deal with the payload

} else {

req.response

..headers.set('Content-Type', 'text/html')

..write('''

<!doctype html>

<html>

<body>

<form action="/" method="post">

<input type="text" name="fname" /><br />

<input type="number" name="age" /><br />

<input type="file" name="photo" /><br />

<button>Save</button>

</form>

</body>

</html>

''')

..close();

}

}

Requests to the server are treated as a Stream , which means that we can use the request’s transform method to decode the content.

if (req.method == 'POST') {

var content = await req.transform().join();

} ...

This won’t work straightaway because the transform method requires a StreamTransformer . A StreamTransformer contains a bind method that allows it to manipulate the streaming data somehow. We need one to transform our streaming data into a readable format, and afterwards use the join method to combine our transformed chunks.

Beneath our dart:io import, let’s require the dart:convert library:

import 'dart:io';

import 'dart:convert';

And use the Utf8Decoder as our transformer:

var content = await req.transform(Utf8Decoder()).join();

Printing out content will give you the below result, provided you filled in the form with the relevant details:

fname=John&age=30&photo=file.jpg

However, we still need to extract our key/value pairs of information from the query string. Fortunately, we have a Uri class in the core Dart SDK:

var content = await req.transform(Utf8Decoder()).join();

var queryParams = Uri(query: content).queryParameters;

3. Respond to the POST

Now let’s send back a response:

var content = await req.transform(Utf8Decoder()).join();

var queryParams = Uri(query: content).queryParameters; req.response

..write('Parsed data belonging to ${queryParams['fname']}')

..close();

UPDATE 20/10/2018: Tobe O(Creator of Angel) helpfully pointed out the use of splitQueryString static method to extract the query parameters:

// var queryParams = Uri(query: content).queryParameters;

var queryParams = Uri.splitQueryString(content);

Our query params are returned as a Map object, allowing us to pull our values like this:

queryParams['fname'];

queryParams['age'];

queryParams['photo'];

The response from our POST request

Here’s the full solution:

The finished code 🎯

In closing…

Like the related article, this works if the payload content type is application/x-www-form-urlencoded and would require a different approach if parsing other content types. We’ll look at this in a future article.

Subscribe to the Youtube channel for upcoming videos on Dart. Thanks!

Like, share and follow me 😍 for more content on Dart.