I am trying to write simple HTTP server which parse result of client.getUrl(). I've got everything working except I am not able to write back to http request object (print to console works fine).
Relevant code is:
main() {
HttpServer.bind(InternetAddress.ANY_IP_V4, 4040)
.then((HttpServer server) {
print('listening on localhost, port ${server.port}');
server.listen((HttpRequest request) {
Future loadedContent = loadUrl(furl);
loadedContent.then((content) => print(content));
// loadedContent.then((content) => request.response.write(content));
request.response.close();
print ("response closed");
});
}).catchError((e) => print(e.toString()));
}
Problem is that main function ends before I get result from Future (figured that out by printing "response closed" which appears second before results). Is there way to wait for results in main function?
Edit: It is related to Dart HttpRequest return future I will rewrite my code, but if there is a way to wait for getUrl Future in main function, I would prefer it.
Edit: my loadUrl
Future loadUrl(String url)
{
final c = new Completer();
HttpClient client = new HttpClient();
client.addCredentials(
Uri.parse("https://*****.tpondemand.com/api"),
"tprealm",
new HttpClientBasicCredentials("*****", "*****"));
client.getUrl(Uri.parse(url))
.then((HttpClientRequest request) {
// Optionally set up headers...
// Optionally write to the request object...
// Then call close.
return request.close();
})
.then((HttpClientResponse response) {
// Process the response.
//print(response.reasonPhrase);
response.transform(UTF8.decoder).listen((contents) {
// handle data
Map parsedMap = JSON.decode(contents);
c.complete(parsedMap);
//req.response.write(parsedMap["Items"][0]);
});
});
return c.future;
}
last edit: this is working code
import 'dart:io';
import 'dart:async';
import 'package:http_server/http_server.dart';
import 'dart:convert';
final furl = "https://***.tpondemand.com";
Future loadUrlBody(String url) {
final c = new Completer();
HttpClient client = new HttpClient();
client.addCredentials(Uri.parse("https://***.tpondemand.com/api"), "tprealm", new HttpClientBasicCredentials("user", "password"));
client.getUrl(Uri.parse(url))
.then((HttpClientRequest response) => response.close())
.then(HttpBodyHandler.processResponse)
.then((HttpClientResponseBody body) {
c.complete(body);
});
return c.future;
}
main() {
final filter = "/api/v1/Userstories?format=json&where=(Team.Id+eq+111111)&include=[Name,CreateDate,ModifyDate,LastCommentDate]&take=1000";
HttpServer.bind(InternetAddress.ANY_IP_V4, 4040).then((HttpServer server) {
print('listening on localhost, port ${server.port}');
server.listen((HttpRequest request) {
print(request.connectionInfo.remoteAddress);
loadUrlBody(furl + filter).then((content) {
Map parsedMap = content.body;
//print("Map parsed");
request.response.write(parsedMap["Items"]);
request.response.close();
//print("response closed");
}).catchError((e) => print(e.toString()));
});
}).catchError((e) => print(e.toString()));
}
When your
loadUrl()
returns a Future (which it probably should) then this should workupdate
You need to modify your
getData()
orloadUrl()
methodupdate 2
Normally it should be sufficient to prepend a
return
before each call to a method that returns a Future, then you can avoid using a completer. Completer are only for more complex situations (for example when you return the completer.future from one method but complete it from somewhere else, for example an event handler).