How to get dependency resolved in a parent to inherit down to a child modal view

According to ui-router docs:

What Do Child States Inherit From Parent States?
Child states DO inherit the following from parent states:
Resolved dependencies via resolve
Custom data properties
Nothing else is inherited (no controllers, templates, url, etc).

I have the following in app.js:

$stateProvider.state('app.manage', {
        url: "/manage",
        views: {
          'menuContent': {
            templateUrl: "manage/templates/manage.html",
            controller: 'ManageCtrl',
            resolve: {
              shop: function (shopService) {
                return shopService.getShop();
              }
         }
      }
    }
  });

  $stateProvider.state('app.manage.hours', {
    url: "/manage/hours",
    resolve: {
      shop: function (shopService) {
        return shopService.getShop();
      } 
    },
    views: {
      'hours': {
        templateUrl: "lib/rcalendar/template/schedule.html",
        controller: "CalendarController"
      }
    }
  }); 

And in my modal template:

<ion-modal-view id="sched-modal">
  <ion-header-bar>
    <h1 class="title">Tuesday 2/6 Schedule</h1>
  </ion-header-bar>
  <div id="sched-subheader" class="bar bar-subheader">
    <h2 id="hour-header">Hours</h2>
    <h2 id="jobs-header">Jobs</h2>
  </div>
  <ion-content id="hours-scroll">
    <ul class="hours">
      <li class="start">{{openTime}}</li>
      <li class="subsequent" ng-repeat="hour in hours">{{hour.val}}</li>
    </ul>
  </ion-content>
</ion-modal-view>

The view where the modal is called from:

<div class="weekview-allday-table">
  <div class="weekview-allday-content-wrapper">
    <table class="table table-fixed" style="height: 100%; margin-bottom: 0px">
      <tbody>
        <tr>
          <td ng-click="openModal();">Set Time</td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

My parent Controller:

myApp.controller('ManageCtrl', function ($scope, shopService, shop) {
  $scope.shop = shop;
});

My Child Controller:

myApp.controller('CalendarController', ['$scope', '$ionicModal', 'shopService', 'shop',  function ($scope, $ionicModal, shopService, shop) {

        //Open the hour view for the selected day
        $ionicModal.fromTemplateUrl('lib/rcalendar/template/schedule.html', {
          scope: $scope,
          animation: 'slide-in-up'
        }).then(function (modal) {
          $scope.modal = modal;
        });
        $scope.openModal = function () {
          console.log("******  Open Modal ******* ");
          console.log(shop.openTime);  
          $scope.modal.show();
        };

        $scope.closeModal = function () {
          $scope.modal.hide();
        };

        $scope.$on('$destroy', function () {
          $scope.modal.remove();
        });

        //Create an array of hours that represents the repair shop's operating hours
        $scope.parseTime = function (timeStr, dt) {
            if (!dt) {
                dt = new Date();
            }

            var time = timeStr.match(/(\d+)(?::(\d\d))?\s*(p?)/i);
            if (!time) {
                return NaN;
            }
            var hours = parseInt(time[1], 10);
            if (hours == 12 && !time[3]) {
                hours = 0;
            }
            else {
                hours += (hours < 12 && time[3]) ? 12 : 0;
            }

            dt.setHours(hours);
            dt.setMinutes(parseInt(time[2], 10) || 0);
            dt.setSeconds(0, 0);
            return dt;
        }

        $scope.shop = shop;

        $scope.hours = [];
       
        //Make an array oh operating hours from open and close time to show on the schedule
        $scope.makeHours = function () {
          var start = $scope.parseTime(shop.open);
          var end = $scope.parseTime(shop.close);
          for(var d = start; d < end; d.setHours(d.getHours() + 1)){
            $scope.hour = {};
            $scope.hour.val = d.toLocaleTimeString('en-US', {hour: '2-digit', minute: '2-digit'});
            $scope.hours.push($scope.hour);
            console.log($scope.hour.val);
          }
          $scope.openHourObj = $scope.hours.shift();
          $scope.openTime = $scope.openHourObj.val;
          console.log($scope.hours);
          console.log($scope.openTime);
        }

        $scope.makeHours();  

When I put makeHours() and parseTime() in the Manage Controller I can console.log that my service brings the information into the Manage Controller. But my week.html view(a section inside the view controlled by the Manage Controller) that calls the modal is set to the Calendar Controller. As is the view loaded within the modal. So it makes more sense to move make Hours() and ParseTime there.

The problem is that when I do that and try to use the resolved shop inside Calendar Controller by passing shop and shopService to my Calendar Controller as works with my Manage Controller I get:

Error: [$injector:unpr] Unknown provider: shopProvider <- shop <- CalendarController

If I remove passing shop to the Calendar Controller I get that shop is undefined.

How does resolved dependency inheritance work in this situation?

Is there anyway u can simplify the example or at a minimum put it in a codepen? Also looks like some of the UI router code for the app state is missing? Cannot follow where the view for the modal is residing.

I just posted this as an issue over at UI-Router’s Github repo. You can see a simplified example there https://github.com/angular-ui/ui-router/issues/1776

took a look, is the HTML posted somewhere? It seems to be the missing link for me to wire it up?

The markup labeled modal template above is what is referenced in app.js as schedule.html. The view where the modal template gets called from is week.html. These both fall under the (child)calendar controller. manage.html operates under the ManageCtrl and has a directive(<calendar>) in it that renders as week.html. I’ve posted it below.

<ion-view title="Scheduling">
  <ion-nav-buttons side="left">
    <button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
  </ion-nav-buttons>
  <ion-content class="has-header" style="position:relative;">
    <calendar id="week-cal" calendar-mode="mode" event-source="eventSource">
  </ion-content>
</ion-view>

resolve should go on view part:

$stateProvider.state('app.manage.hours', {
    url: "/manage/hours",
    views: {
      'hours': {
        templateUrl: "lib/rcalendar/template/schedule.html",
        controller: "CalendarController",
        resolve: {
          shop: function (shopService) {
            return shopService.getShop();
          } 
        }
      }
    }
  });

But I don’t need to do route promise to pass scope variable between parent and child states. Try adding abstract: true to your parent state…

I see a lot of demos which show using abstract true on the parent. But in my situation the parent state is one in which I need to be able to navigate to. Abstract true prevents this. Is it possible to get data resolved in a parent that is not set to abstract true to inherit that data down to the child view?

I don’t know,

But you can solve this by simply refactoring your states? i would do app.manage as abstract, and then app.manage.home, app.manage.hours etc… Define $scope.var on abstract state controller and then just assign it in any child.