7

I have the following routes:

$stateProvider
    .state("base",
    {
        url: "",
        abstract: true,
        resolve: {
            aService: "aService",
            dataNeeded: function(aService) {
            return aService.getDataMethod().$promise;
            }
        },
        template: "<ui-view/>",
    });


$stateProvider
    .state("base.main",
    {
        url: "/",
        templateUrl: coreConfig.path() + "/modules/content/content.tmpl.html",
        controller: "aController",
        controllerAs: "aCtrl",
        data: { requiresLogin: true }
    });

I'm using an abstract route to resolve data required in the child 'base.main' route.

and in my app.js file I have

angular.module("aModule", ["CoreModule"])
    .controller({ "aController": require("./modules/content/aController.controller.js") });

I have my controller:

 module.exports = ["aService", "dataNeeded", aController];

    function aController(aService, dataNeeded) {
        var test = dataNeeded; //value is undefined
    }

How do I access the 'dataNeeded' loaded in the abstract route from within the `'base.main' controller?

3 Answers 3

5

Every child state can ask for resloved stuff from its parent(s), so this would work

.controller('aController', ['$scope', 'dataNeeded', 
   function ($scope, dataNeeded) { 
     ...
}])

Check this related Q & A:

Angularjs ui-router abstract state with resolve

And its working example

EXTEND

There is another working example related to our scenario:

States:

$stateProvider
    .state("base", {
      url: "",
      abstract: true,
      resolve: {
        aService: "aService",
        dataNeeded: function(aService) {
          return aService.getDataMethod(); //.$promise;
        }
      },
      template: "<ui-view/>",
    });

$stateProvider
    .state("base.main", {
      url: "/main",
      //templateUrl: coreConfig.path() + "/modules/content/content.tmpl.html",
      templateUrl: 'tpl.main.html',
      controller: "aController",
      controllerAs: "aCtrl",
      data: {
        requiresLogin: true
      }
    });
  }
])

Controller and service:

.controller('aController', ['$scope', 'dataNeeded', 'aService',
    function($scope, dataNeeded, aService) {
      $scope.dataNeeded = dataNeeded;
      $scope.aService = aService;
    }
])
.factory('aService', function() {
    return {
      getDataMethod: function() {
        return { name:  "abc", id : 1 }
      }
    }
})

And a template which will render both 'dataNeeded', 'aService' :

<h5>aService</h5>
  <b>{{aService}}</b>
<h5>dataNeeded</h5>
  <pre>{{dataNeeded | json}}</pre>

The example in action here

MORE EXTEND

Another, more extended example could be loading data.json:

{ "name":  "def", "id" : 22 }

The servcie would then be

.factory('aService', ['$http', function($http) {
    return {
      getDataMethod: function() {
        return $http.get("data.json");
      }
    }
}])

And parent abstract resolve:

  resolve: {
    aService: "aService",
    dataNeeded: function(aService) {
      return aService.getDataMethod()
        .then(function(response){ return response.data }); //.$promise;
    }
  },

Check that here in action

Sign up to request clarification or add additional context in comments.

5 Comments

I thought I could access the data as you have indicated. However, the data is not injected as expected. See my edit to the question.
I've taken your example code, and created working plunker showin that all in action. The only change is, that I have no idea what should be the aService.getDataMethod().$promise; so in that case I just decided to use aService.getDataMethod()
And do you know what, I decided to even show you how to consume return server request... check the extended answer part and its special working example
These are great examples. However, i think the issue I'm having is related to how my controllers are created using require.js
I am doing my best to assist you and you now reveal that your scenario is different ... well ...
3

Based on this Q & A

angular-ui-router with requirejs, lazy loading of controller

I created this working plunker, which is able to load controller with RequireJS and inject state resolve - from Parent or from the Child itself

This would be the state defintion:

$stateProvider
  .state("base",
  {
    abstract: true,
    resolve: {
        dataNeeded: function(aService) {
          return aService.getDataMethod()
            .then(function(response){ return response.data }); //.$promise;
        }
    },
    template: "<ui-view/>",

  });

$stateProvider
  .state("base.other", {
    url: "/other",
    template: "<div>The message from ctrl: {{message}}" +
    "<br>and someResolved: <b>{{someResolved}}<b>" +
    "<br> and dataNeeded: <pre>{{dataNeeded | json}}</pre>" +
    "</div>",
    controller: "OtherCtrl", 
    resolve: {
      someResolved: function() { return "This is resolved value for key 'someResolved'" },
      loadOtherCtrl: ["$q", function($q) { 
        var deferred = $q.defer();
        require(["OtherCtrl"], function() { deferred.resolve(); });
        return deferred.promise;
      }],
    },
  });

For more details read complete explanation here...

And this is the controller for RequireJS:

define(['app'], function (app) {
    // the Default Controller
    // is added into the 'app' module
    // lazily, and only once
    app_cached_providers
      .$controllerProvider
      .register('OtherCtrl',['$scope', 'dataNeeded', 'aService', 'someResolved', 
        function ($scope, dataNeeded, aService, someResolved) {
          $scope.message = "OtherCtrl";
          $scope.someResolved = someResolved;
          $scope.dataNeeded = dataNeeded;
          console.log(dataNeeded)
          console.log(aService)
          console.log(someResolved)
    }]);

});

Check it here in action

Comments

0

In your app.js

  resolve:{
      aService: "aService",
      dataNeeded: function(aService) {
        return aService.getDataMethod().$promise;
      }
   },

In your controller :

app.controller('ServiceController', [
    'aService',
    'dataNeeded',
    function(aService, dataNeeded ) {
   ...
}];

Now, you access 'aService' and the 'dataNeeded' loaded inside your controller 'ServiceController'.

1 Comment

I thought I could access the data as you have indicated. However, the data is not injected as expected. See my edit to the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.