0

I am trying to fetch html page via localproxy to parse and get urls from it. I can't find any library which works without Future in Dart. So i have difficulty returning String from a Future Object. Below is full code of dart file.

import 'package:universal_html/driver.dart';
import 'package:universal_html/prefer_universal/html.dart';

String proxyUrl='http://localhost/php-proxy/index.php?q=';
String hallTicketUrl='http://www.ignou.ac.in/ignou/studentzone/results/6';

Future<String> getList()async{
  final driver = HtmlDriver();
  await driver.setDocumentFromUri(Uri.parse(proxyUrl+hallTicketUrl));
  final items = driver.document.querySelectorAll('.middleconten2column a');

  Element urls=Element.tag('urls');
  items.forEach((item)=>urls.append(Element.tag('url')
                        ..setAttribute('href',item.getAttribute('href'))
                        ..text=item.text
                        )
        );
  print('${items.length} items found');

return Future.value(urls.outerHtml);
}

String Handler(String app){
    switch(app){
       case 'list': return getList() as String;
}
return "";
}

main(){
    print(Handler('list'));
}

1 Answers1

1

I think you have misunderstood what the async keyword does to methods. When a method are marked as async it will always automatically returns a Future of something. That is the reason why you need to specify e.g. Future<String> as the return type.

But because the creation are done "automatically" you don't really need to do the following:

return Future.value(urls.outerHtml);

But can just do:

return urls.outerHtml;

After this your have discovered the problem with using asynchronous programming where everything in your call stack needs to be marked as async since you have an await somewhere in your code.

I have fixed your code so it now hope it works correctly with all the future stuff:

import 'package:universal_html/driver.dart';
import 'package:universal_html/prefer_universal/html.dart';

String proxyUrl = 'http://localhost/php-proxy/index.php?q=';
String hallTicketUrl = 'http://www.ignou.ac.in/ignou/studentzone/results/6';

Future<String> getList() async {
  final driver = HtmlDriver();
  await driver.setDocumentFromUri(Uri.parse(proxyUrl + hallTicketUrl));
  final items = driver.document.querySelectorAll('.middleconten2column a');

  Element urls = Element.tag('urls');
  items.forEach((item) => urls.append(Element.tag('url')
    ..setAttribute('href', item.getAttribute('href'))
    ..text = item.text));
  print('${items.length} items found');

  return urls.outerHtml;
}

Future<String> Handler(String app) async {
  switch (app) {
    case 'list':
      return await getList();
  }
  return "";
}

main() async {
  print(await Handler('list'));
}
julemand101
  • 28,470
  • 5
  • 52
  • 48
  • Thanks I learned new things. But still i can't understand how can i use it everywhere by making class/library of it i.e. in command-line, javascript and in server programs. e.g. someone called an api on server and handler handles request, how can it return xml/json independently from Future Object. – Ravi Kanojia Nov 28 '19 at 12:18
  • I tried with shelf server and cant assign the same handler('list') output to response. – Ravi Kanojia Nov 28 '19 at 12:45
  • shelf.Response _echoRequest(shelf.Request request){ shelf.Response.ok('Request for "${request.url}"\n'+ht.handler('list')); } – Ravi Kanojia Nov 28 '19 at 13:08
  • Please update your question with details about your new problem or create a new question. It is difficult to help you without any context of your code. – julemand101 Nov 28 '19 at 13:51
  • Please check this https://stackoverflow.com/questions/59090393/server-response-with-output-from-future-object – Ravi Kanojia Nov 28 '19 at 13:51
  • Do you need more information before you can accept my answer? – julemand101 Nov 28 '19 at 18:21
  • Future.value is what I was looking for, thanks! – Soufiane Sabiri Jan 07 '22 at 22:26