Accessing parent component variables in child component (ng-view nested routes)

Issue

My ‘admin’ route has a mounting called ‘edit/:category’.

I want to access the variables declared inside the component named ‘edit_menuitem_controller’ which has a variable say menuItemMap. I was once able to access it inside the ‘editor_controller’s custom element named ” like this:

<editor menu-item-map="menuItemMap"></editor>

but now, it says menuItemMap is null and it doesn’t pick up the value from the parent component even when the parent view is still there.

I had referred to this project and was able to achieve my goals before but it has outdated code now: https://github.com/vadimtsushko/angular_objectory_demo

edit_menuitem_controller.dart:

@Component(
selector:'edit-menu-item',
  templateUrl: 'edit_menuitem_controller.html',
  useShadowDom: false
)
class EditMenuItemController implements ScopeAware{
  final Http _http;
  final QueryService _queryService;
  final CommonService _commonService;
  final Router _router;
  final RouteProvider _routeProvider;

  bool menuItemsLoaded = false;

  Map<String, MenuItem> _menuItemMap = {};
  Map<String, MenuItem> get menuItemMap => _menuItemMap;
  List<List<MenuItem>> _properMenuItems = [];
  List<List<MenuItem>> get properMenuItems => _properMenuItems;
  List<String> _categories = [];
  List<String> get categories => _categories;
  EditMenuItemController(this._http,this._queryService, this._commonService,this._router, this._routeProvider, this.modal){}

  void selectCategory(String category){
    _router.go('edit-mode', {'category':category}, startingFrom: _router.root.findRoute('admin'));
  }
}

selectCategory() function goes to required route and starts the editor_controller

editor_controller.dart

@Component(
    selector: 'editor',
    templateUrl: 'editor_controller.html',
    useShadowDom: false
)
class EditorController{

  final Router _router;
  final RouteProvider _routeProvider;
  final QueryService _queryService;

  @NgOneWay('proper-menu-items')
  List<List<MenuItem>> properMenuItems;


  String _selectedCategory;
  List<MenuItem> _categoryWiseItems = [];
  List<MenuItem> get categoryWiseItems => _categoryWiseItems;

  EditorController(this._router,this._routeProvider,this._queryService){
    _selectedCategory = _routeProvider.parameters['category'];
    if(properMenuItems != null){
      properMenuItems.forEach((list){
        if(_selectedCategory == list.first.category){
          _categoryWiseItems = list;
        }
      });
    }
    else{
      print("properMenuItems is null");
    }
  }

always gives me “properMenuItems is null”

my routing config is like this:

restaurant_router.dart

void restaurantRouteInitializer(Router router, RouteViewFactory views){
  views.configure({
    'add': ngRoute(
        path: '/add',
        view: 'view/addMenuItem.html'),
    'admin': ngRoute(
        path: '/admin',
        view: 'view/editMenuItem.html',
        mount: {
          'edit-mode': ngRoute(
              path: '/edit/:category',
              view: 'view/editor.html')
        }),
    'view': ngRoute(
        path: '/view',
        view: 'view/menuController.html'
        ),
    'kitchen': ngRoute(
        path: '/kitchen',
        view: 'view/kitchen.html'
        ),
    'register_table': ngRoute(
        path: '/table/:table_num',
        viewHtml: '<register-table></register-table>'),
    'test': ngRoute(
        path: '/test',
        viewHtml: '<test></test>'),
    'default_page': ngRoute(
        defaultRoute: true,
        enter: (RouteEnterEvent e){
          router.activePath.forEach((e){
            print("Something to do with router : ${e}");
          });
          router.go('view', {});
        })
  });
}

and finally my html:

edit_menuitem_controller.html

<div ng-switch="menuItemsLoaded">
  <div ng-switch-when="false">

  </div>
  <div ng-switch-when="true">
    <span class="hide">{{allMenuItems.length}}</span>
    <div class="wrap">
      <!--SIDEBAR-->
      <div class="col-md-2 sidebar">
        <div class="row">
          <section> 
            <h4 class="sidebar-head"><span class="fa fw fa-sliders"></span> &nbsp;Dashboard</h4>
          </section>
          <div class="border"></div>
          <section>
            <p class="section-head">BASIC SETTINGS</p>
            <p><a href=""><span class="fa fw fa-eye"></span> &nbsp;Preview</a></p>
            <p><a href=""><span class="fa fw fa-bookmark"></span> &nbsp;Another Preview</a></p>
          </section>
          <section>
            <p class="section-head">Menu categories</p>
            <span ng-repeat="list in properMenuItems">
            <p class="pointer" ng-click="selectCategory(list.first.category)"><a><span class="fa fw caret-right"></span> &nbsp;{{list.first.category}}</a></p>
            </span>
            </section>
          <section>
            <p class="section-head">general Settings</p>
            <p><a href=""><span class="fa fw fa-cog"></span> &nbsp;Info Settings</a></p>
            <p><a href=""><span class="fa fw fa-desktop"></span> &nbsp;Display Settings</a></p>
          </section>
          <div class="border"></div>
          <section>
            <p class="section-head">Add Item</p>
            <p><a href=""><span class="fa fw">{{allMenuItems.length}}</span> &nbsp;Total Items</a></p>
            <p class="add-another"><a href=""><span class="fa fw fa-plus"></span> &nbsp;Add an item</a></p>
          </section>
        </div>
      </div> <!--./col-->
      <!--BLOG COLUMN-->

      <div class="col-md-10 col-md-push-2 gen-sec">

       <div class="well">
         <p>Sample
         </p>
       </div>

<!-- HERE IS THE NESTED VIEW -->
       <ng-view></ng-view>

      </div><!-- ./col -->
     <div style="clear:both"></div>       
   </div>
</div>
</div>

Solution

The constructor gives values of the attributes of the element even before they were attached. So we needed to implement AttachAware and listen to attach() and then only do further operations.

I modified my code to allow proper execution like this:

editor_controller.dart

@Component(
    selector: 'editor',
    templateUrl: 'editor_controller.html',
    useShadowDom: false
)
class EditorController implements AttachAware{

  final Router _router;
  final RouteProvider _routeProvider;
  final QueryService _queryService;

  @NgOneWay('menu-item-map')
  Map<String, MenuItem> menuItemMap;
  @NgOneWay('proper-menu-items')
  List<List<MenuItem>> properMenuItems;
  @NgOneWay('categories')
  List<String> categories;

  String _selectedCategory;
  List<MenuItem> _categoryWiseItems = [];
  List<MenuItem> get categoryWiseItems => _categoryWiseItems;

  EditorController(this._router,this._routeProvider,this._queryService){
    _selectedCategory = _routeProvider.parameters['category'];
    /*
    print("menuItemMap is $menuItemMap");
    print("properMenuItems is $properMenuItems");
    print("categories is $categories");

    always gave null
    */
  }

  void attach(){
    /*
    print(menuItemMap);
    print(properMenuItems);
    print(categories);

    prints values as intended
    */

    if(properMenuItems != null){
      properMenuItems.forEach((list){
        if(_selectedCategory == list.first.category){
          _categoryWiseItems = list;
        }
      });
    }
    else{
      print("properMenuItems is null");
    }

  }

Answered By – Sid

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.