Z. Charles Dziura
Z. Charles Dziura

Reputation: 933

Angular UI Router - How to Pass Resolve Data to a Nested View from Parent State

I'm currently working on an Angular web application which will display various types of financial events for the user. These events are tied together under one ID, organized into different groups. Each of these groups needs to be displayed in their own separate HTML <table>.

That financial data is retrieved using an Angular Service, and resolved within the Angular UI Router configuration. All of the data is also stored within that same Service.

Below is the current Router configuration:

import EventsController from './events.controller';
import EventsService from './events.service';
import EventsTableController from './events-tables/events-table.controller';

import eventsView from './events.html';
import eventsDetailsTableView from './events-tables/details-table.html';

export default function routes($stateProvider) {
    $stateProvider
        .state('events', {
            url: '/events/{payDate:string}',
            template: eventsView,
            controller: EventsController,
            controllerAs: 'events',
            resolve: {
                eventsData: ['$http', '$stateParams', ($http, $stateParams) => {
                    return new EventsService($http, $stateParams);
                }]
            },
            views: {
                'details@': {
                    template: eventsDetailsTableView,
                    controller: EventsTableController,
                    controllerAs: 'details',
                    resolve: {
                        eventData: 'eventsData.details'
                    }
                }
            }
        }
    );
}

routes.$inject = ['$stateProvider'];

In the future, the EventsController will be used to filter which <table>s will be displayed based on the user's preference.

The EventsTableController is a generic Controller which stores both the type of data being displayed (in this example, "details"), and the data itself, stored as a two-dimensional array.

export default class EventsTableController {
    constructor(eventData) {
        this.name = eventData.name;
        this.data = eventData.data;
        console.log(this)
    }
}

Also for reference, here's an example of the data being returned from the Service:

{
    'details': [[
        "Event-ID",
        "Company-CUSIP",
        "Company-Name"]
    ]
}

Each <table> will correspond to a different field within that object.

I'm having trouble, however, passing the data from the 'events' state's resolve into the nested details@ view. The above configuration returns an error, stating that Angular UI Router is unable to find the specific dependency: 'eventsData.details'.

My question is this: how do I pass individual object fields into the nested views, such that they can all be independently displayed? If there is any more source information that I can provide, please let me know and I'll amend this post for clarity.

Upvotes: 1

Views: 2903

Answers (1)

Ori Drori
Ori Drori

Reputation: 191976

By default resolves from parent are available in child states, and named views.

If you have multiple named views inside a state, and they need to use one of the state's resolves, you can inject them normally in the controller, for example:

EventsTableController.$inject = ['eventsData
function EventsTableController(eventsData) {
    console.log(eventsData);
}

Child states also inherit resolved dependencies from parent state(s). For example (resA):

$stateProvider.state('parent', {
      resolve:{
         resA:  function(){
            return {'value': 'A'};
         }
      },
      controller: function($scope, resA){
          $scope.resA = resA.value;
      }
   })
   .state('parent.child', {
      resolve:{
         resB: function(resA){
            return {'value': resA.value + 'B'};
         }
      },
      controller: function($scope, resA, resB){
          $scope.resA2 = resA.value;
          $scope.resB = resB.value;
      }

Upvotes: 4

Related Questions