Dart HTTPClient Response query - dart

I would like to make the below functionality synchronous. The "onDataLoaded" needs to be called once the stream has been read completely. Please suggest what changes needs to be done.
String JsonContent="";
new HttpClient().getUrl(Uri.parse(uri))
.then((HttpClientRequest request)
{
request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING);
return request.close();
})
.then((HttpClientResponse response)
{
response.transform(UTF8.decoder).listen((contents) {
JsonContent = contents.toString();
print(JsonContent);
//onDataLoaded(JsonContent);
});
});

this should work
import 'dart:io';
import 'dart:convert' show UTF8;
void main(args) {
String JsonContent="";
new HttpClient().getUrl(Uri.parse(uri))
.then((HttpClientRequest request)
{
request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING);
return request.close();
})
.then((HttpClientResponse response)
{
response.transform(UTF8.decoder).listen((contents) {
JsonContent = contents.toString();
print(JsonContent);
//onDataLoaded(JsonContent);
}, onDone: () => onDataLoaded(JsonContent));
});
}
void onDataLoaded(String jsonContent) {
print(jsonContent);
}

Related

How to use dart shelf_router in web only dart project

From the example given at this place :
https://pub.dev/packages/shelf_router/example
I have written the router part like this :
class Service {
Handler get handler {
final router = Router();
router.get('/say-hi/<name>', (Request request, String name) {
return Response.ok('hi $name');
});
router.get('/user/<userId|[0-9]+>', (Request request, String userId) {
return Response.ok('User has the user-number: $userId');
});
router.get('/wave', (Request request) async {
await Future.delayed(Duration(milliseconds: 100));
return Response.ok('_o/');
});
router.mount('/api/', Api().router);
router.all('/<ignored|.*>', (Request request) {
return Response.notFound('Page not found');
});
return router;
}
}
class Api {
Future<Response> _messages(Request request) async {
return Response.ok('[]');
}
Router get router {
final router = Router();
router.get('/messages', _messages);
router.get('/messages/', _messages);
uter.all('/<ignored|.*>', (Request request) => Response.notFound('null'));
return router;
}
}
and from the main method it tells to use it like this:
void main() async {
final service = Service();
final server = await shelf_io.serve(service.handler, 'localhost', 8080);
print('Server running on localhost:${server.port}');
}
but in web-only project we don't do : final server = await shelf_io.serve(service.handler, 'localhost', 8080);
I was thinking of creating single page application using a shelf router, I saw from the documentation it says that it is compatible with the dart web js platform
My expectation was :
if I write this in web :
router.get('/say-hi/<name>', (Request request, String name) {
return Response.ok('hi $name');
});
then when I will hit /say-hi/ram, then it should have returned "hi ram" in the browser

Flutter dart function skipping to end of function after await

I have a function with the keyword async and after the await is done, it skips a bunch of lines of codes and goes to the end of the function after the await is done. Does anyone know what I am doing wrong?
void _createNewGroup(Function createNewGroup, BuildContext context) async {
if (_validateAndSave()) {
try {
print("trying");
Map<String, dynamic> result = await createNewGroup(_group_name);
print("sucess is $result");
if (result['success']) {
print('Success poping dialoge');
Navigator.of(context).pop();
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (context) => HomePage()));
} else {
print("not created group");
}
} catch (error) {}
}
}
Future<Map<String, dynamic>> createNewGroup(String name) async {
var result = {};
var response;
print('Group name $name');
print("creating group");
var group = ParseObject('Groups')
..set("group_name", name)
..set('createdBy_name', _parseUser.get('first_name'))
..set('CreatedBy_id', _parseUser.objectId)
..set('members', [{'name': _parseUser.get('first_name'), 'id': _parseUser.objectId}]);
response = await group.save();
if(response.success) {
print('sucess creating object');
result = {'success': true, 'message': 'New Group Created'};
return result;
} else {
result = {'success': false, 'message': 'Error occured creating group'};
}
print("result is $result");
print("response is ${response.result}");
return result;
}

Dart Language: GET (favicon issue)

I have a Dart application running on the server side. It is listening at a specific port and working fine. The problem is: my listener is responding to the GET of the favorite icon (favicon).
How can I avoid that?
EDIT: give some code example.
import 'dart:io';
void main() {
print("Starting server.");
HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 4041)
.then(listenForRequests)
.catchError((e) => print (e.toString()));
}
listenForRequests(HttpServer _server) {
_server.listen((HttpRequest request) {
if (request.method == 'GET') {
handleGet(request);
} else {
request.response.statusCode = HttpStatus.METHOD_NOT_ALLOWED;
request.response.write("Unsupported request: ${request.method}.");
request.response.close();
}
},
onDone: () => print('No more requests.'),
onError: (e) => print(e.toString()) );
}
void handleGet(HttpRequest request) {
int requestNumber = 1;
print(requestNumber); // This shows me the request number. Just for information.
print(request.uri); // This shows me the request from the client browser.
request.response.statusCode = HttpStatus.OK;
request.response.close();
}
This is the output of this code:
1
/SOME_REQUEST_FROM_THE_BROWSER
2
/favicon.ico
You can check the requested resource and generate proper response for requests to 'favicon.ico' like
void handleGet(HttpRequest request) {
int requestNumber = 1;
print(requestNumber++); // This shows me the request number.
print(request.uri); // This shows me the request from the client browser.
if(request.requestedUri.path != '/favicon.ico') {
request.response.statusCode = HttpStatus.NOT_FOUND;
} else {
request.response.statusCode = HttpStatus.OK;
}
request.response.close();
}

Dart is too fast

I'm trying to understand why this code print "check" twice...
import 'dart:io';
import 'dart:async';
import 'dart:convert';
Future<Map> ft_get_data() {
File data;
data = new File("data.json");
return data.exists().then((value) {
if (!value) {
print("Data does no exist...\nCreating file...");
data.createSync();
print("Filling it...");
data.openWrite().write('{"index":{"content":"Helllo"}}');
print("Operation finish");
}
}).then((_) => data.readAsString()).then((content) => JSON.decode(content)
).catchError((e) => new Map());
}
void main() {
Map params;
String name;
num check = 0;
HttpServer.bind('127.0.0.1', 8080).then((server) {
print("Server is lauching... $server");
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
request.response.headers.contentType = new ContentType('text', 'htm l');
params = request.uri.queryParameters; // http://127.0.0.1:8080/?name=tristan
ft_get_data().then((data_map) {
name = data_map['index']['content'];
print('check: $check');
if (data_map.isNotEmpty) request.response.write(name); else
request.response.write('Booh');
check++;
}).whenComplete(request.response.close);
});
}).catchError((error) {
print("An error : $error.");
});
}
Is it too fast ? Or there exist some method to make a pause ? Thank you.
I tried your code and it prints 0.
What client are you using to access the server?

Dart get back value of function

I'm trying to learn Dart by my self, but I come from C and I a bit confused...
I'm doing this :
import 'dart:io';
import 'dart:async';
import 'dart:convert';
Future <Map> ft_get_data()
{
File data;
data = new File("data.json");
return data.exists().then((value) {
if (!value)
{
print("Data does no exist...\nCreating file...");
data.createSync();
print("Filling it...");
data.openWrite().write('{"index":{"content":"Helllo"}}');
print("Operation finish");
}
return (1);
}).then((value) {
data.readAsString().then((content){
return JSON.decode(content);
}).catchError((e) {
print("error");
return (new Map());
});
});
}
void main()
{
HttpServer.bind('127.0.0.1', 8080).then((server) {
print("Server is lauching... $server");
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
ft_get_data().then((data_map) {
if (data_map && data_map.isNotEmpty)
request.response.write(data_map['index']['content']);
else
request.response.write('Not work');
}).whenComplete(request.response.close);
});
}) .catchError((error) {
print("An error : $error.");
});
}
I'm trying to get back the new Map, and as you can guess, it doesn't work and I get the 'Not work' msg. While when the code was in same function, it worked...
Please, could you help me ?
And, there a pointer system as C ?
void function(int *i)
{
*i = 2;
}
int main()
{
int i = 1;
function(&i);
printf("%d", i);
}
// Output is 2.
Thank you for your help.
Final code :
import 'dart:io';
import 'dart:async';
import 'dart:convert';
Future<Map> ft_get_data()
{
File data;
data = new File("data.json");
return data.exists()
.then((value) {
if (!value) {
print("Data does no exist...\nCreating file...");
data.createSync();
print("Filling it...");
data.openWrite().write('{"index":{"content":"Helllo"}}');
print("Operation finish");
}
})
.then((_) => data.readAsString())
.then((content) => JSON.decode(content))
.catchError((e) => new Map());
}
void main()
{
HttpServer.bind('127.0.0.1', 8080)
.then((server) {
print("Server is lauching... $server");
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
ft_get_data()
.then((data_map) {
if (data_map.isNotEmpty)
request.response.write(data_map['index']['content']);
else
request.response.write('Not work');
})
.whenComplete(request.response.close);
});
})
.catchError((error) {
print("An error : $error.");
});
}
I tried to reconstruct your code to "readable" format. I haven't test it, so there might be errors. For me the code is much easier to read if .then() are not nested. Also it helps reading, if .then() starts a new line.
import 'dart:io';
import 'dart:async';
import 'dart:convert';
Future <Map>ft_get_data()
{
File data;
data = new File("data.json");
data.exists() //returns true or false
.then((value) { // value is true or false
if (!value) {
print("Data does no exist...\nCreating file...");
data.createSync();
print("Filling it...");
data.openWrite().write('{"index":{"content":"Helllo"}}');
print("Operation finish");
}
}) // this doesn't need to return anything
.then((_) => data.readAsString()) // '_' indicates that there is no input value, returns a string. This line can removed if you add return data.readAsString(); to the last line of previous function.
.then((content) => JSON.decode(content)); // returns decoded string, this is the output of ft_get_data()-function
// .catchError((e) { //I believe that these errors will show in main-function's error
// print("error");
// });
}
void main()
{
HttpServer.bind('127.0.0.1', 8080)
.then((server) {
print("Server is lauching... $server");
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
ft_get_data()
.then((data_map) {
if (data_map && data_map.isNotEmpty)
request.response.write(data_map['index']['content']);
else
request.response.write('Not work');
})
.whenComplete(request.response.close);
});
})
.catchError((error) {
print("An error : $error.");
});
}
you cannot insert one then() into the other. Need to chain them. Otherwise, return JSON.decode(data) returns to nowhere (main event loop) instead of previous "then" handler
After a brief look I would say you need
Future<Map> ft_get_data() {
...
return data.exists() ...
...
}
and use it like
server.listen((HttpRequest request) {
request.response.statusCode = HttpStatus.ACCEPTED;
ft_get_data().then((data_map) {
if (data_map && data_map.isNotEmpty) request.response.write(
data_map['index']['content']);
else
request.response.write('Not work');
request.response.close();
});
});
A return inside a then doesn't return from ft_get_data but only from then
If an async call is involved you can't continue if it was sync, it's then async all the way down.

Resources