olituks
olituks

Reputation: 487

DART : how can assign the result of httpRequest on a property object?

I would like to save in a Object property (my_json) a JSON List loaded from an external file. With this code my_json properties is always equal to null :{

Thanks in advance for your help :)

@CustomTag('scaffold-toolsbar-element')
class MyCustomTag extends PolymerElement{

  void click_menu_item(String label) {
    shadowRoot.querySelector('#page_name').text = label;
  }

  MyCustomTag.created() : super.created(){

    var menu_list = new MenuList('menu_items.json');

    addElementToMenu(list_value){
      var newElement = new Element.tag('core-item');
      newElement.setAttribute("icon", list_value["icon"]);
      newElement.setAttribute("label", list_value["label"]);
      newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
      shadowRoot.querySelector('#core_menu_item').children.add(newElement);
    };

    menu_list.my_json.forEach(addElementToMenu);
  }
}

class MenuList {
  String path;
  List my_json;

  MenuList(String path) {
    this.path = path;
    var httpRequest = new HttpRequest();
    httpRequest
    ..open('GET', path)
    ..onLoadEnd.listen((e) => requestComplete(httpRequest))
    ..send('');
  }

  requestComplete(HttpRequest request) {
    // request.status is 200 
    // request.responseText is 
    // "[ {"icon": "settings", "label": "Signin", "main_page": "signin-element"}, {"icon": "home", "label": "About", "main_page": "about-page-element"} ]" 
    if (request.status == 200) {
      this.my_json = JSON.decode(request.responseText);
    }else{
      this.my_json = null;
    }
  }
}

Upvotes: 2

Views: 418

Answers (3)

Günter Zöchbauer
Günter Zöchbauer

Reputation: 657466

Your MenuList class could look like

class MenuList {
  String path;
  List my_json;

  static Future<MenuList> create(String path) {
    return new MenuList()._load(path);
  }

  Future<MenuList>_load(String path) {
    Completer completer = new Completer();
    this.path = path;
    var httpRequest = new HttpRequest();
    httpRequest
        ..open('GET', path)
        ..onLoadEnd.listen((e) {
          requestComplete(httpRequest);
          completer.complete(this);
        })
        ..send('');
    return completer.future;
  }

  requestComplete(HttpRequest request) {
    if (request.status == 200) {
      this.my_json = JSON.decode(request.responseText);
    }else{
      this.my_json = null;
    }
  }
}

and the constructor of MyCustomTag like

void attached() {
  super.attached();

  var menu_list;
  MenuList.create('menu_items.json')
  .then((ml) {
    menu_list = ml;
    addElementToMenu(list_value){
      var newElement = new Element.tag('core-item');
      newElement.setAttribute("icon", list_value["icon"]);
      newElement.setAttribute("label", list_value["label"]);
      newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
      shadowRoot.querySelector('#core_menu_item').children.add(newElement);
    };

    menu_list.my_json.forEach(addElementToMenu);
  });
}

I haven't actually tested this code but at leas the analyzer was satisfied.

Upvotes: 1

olituks
olituks

Reputation: 487

The solution come from Robert. I try to read an Object property before the JSON List result is assigned to. So I have always a null property... To avoid that, I add an optional parameter async to my HttpRequest.open like that: ..open('GET', path, async:false)

This is the final code.

@CustomTag('scaffold-toolsbar-element')
class MyCustomTag extends PolymerElement{

  void click_menu_item(String label) {
    shadowRoot.querySelector('#page_name').text = label;
  }

  MyCustomTag.created() : super.created(){

    var menu_list = new MenuList('menu_items.json');

    addElementToMenu(list_value){
      var newElement = new Element.tag('core-item');
      newElement.setAttribute("icon", list_value["icon"]);
      newElement.setAttribute("label", list_value["label"]);
      newElement.onClick.listen((e) => click_menu_item(list_value["label"]));
      shadowRoot.querySelector('#core_menu_item').children.add(newElement);
    };

    menu_list.my_json.forEach(addElementToMenu);
  }
}

class MenuList {
  String path;
  List my_json;

  MenuList(String path) {
    this.path = path;
    var httpRequest = new HttpRequest();
    httpRequest
    ..open('GET', path, async:false)
    ..onLoadEnd.listen((e) => requestComplete(httpRequest))
    ..send('');
  }

  requestComplete(HttpRequest request) {
    if (request.status == 200) {
      this.my_json = JSON.decode(request.responseText);
    }else{
      this.my_json = null;
    }
  }
} 

Upvotes: 1

Robert
Robert

Reputation: 5662

This is the code you require:

HttpRequest.request(path, responseType: 'json').then((HttpRequest request) {
  var json = request.response;
});

Note that there is a bug in Dartium at the moment:

https://code.google.com/p/dart/issues/detail?id=20129

As a workaround you can omit the responseType parameter and use request.responseText.

Regards, Robert

Upvotes: 2

Related Questions