Search code examples
dartdart-async

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;
    }
  }
}

Solution

  • 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.