I have this config and controller in the module:
(function () { "use strict"; angular.module("dashboard", ["ui.router", "clients", "sites", "regions", "beddingTypes", "geomindCommon", ]) .config([ "$stateProvider", function ($stateProvider) { $stateProvider .state("home", { url: "/Menu", templateUrl: "app/dashboard/templates/dashboard.tmpl.html", resolve: { client: ['$window', 'dashboardService', 'config', clientMapResolver], } }); } ]) .controller('dashboardController', ['$scope', 'config', function ($scope, config) { $scope.currClientId = config.currClient.id; } ]) function clientMapResolver($window, dashboardService, config) { var layoutId = $window.parent.parent.parent.location.search.split('=')[1]; } })();
As you can see I have defined resolve in config
state. But resolve is never triggered and clientMapResolver
function is never called.
UPDATE: Maybe this can cause the issuse:
The project is SPA project.The dashboard is main module. I noticed that in my index page I have this diclaration:
<body ng-app="dashboard" ng-strict-di> <div ng-controller="dashboardController"> <div class="sizeResponsive navbar navbar-green navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> </div> </div> </div>
Any idea why resolve is never triggered?
5 Answers
Answers 1
Your issue is that your resolve
block does not map to the correct data type. The purpose of the resolve block is to define dependencies for a controller that this view will be associated with. You are not declaring your controller in this code - you need to have a controller defined that the resolve will be associated with (see the documentation). Once you've done this, resolve should be used for any services that are not elsewhere defined in your app. So you don't need to resolve "$window" or anything like that, just special values that don't already exist. So "client"
would be the name of a dependency injected into your control (matching on the string "client") and the value associated with "client" is what gets injected. So it needs to map to a string (the name of an existing service) or a function that will return the value you want injected. See the documentation: https://github.com/angular-ui/ui-router/wiki#resolve.
Note that I would also discourage anything resembling $window.parent.parent.parent.location.search
. You've really got too many iframes if you need to do that.
Answers 2
Resolve is inject-able in controller, so Resolve need to return something to get values or anything...
Also you can make resolve return value as Promise using service function directly, in this case you don't need to add functions in your
app.config
Where we have to use resolve?
Sometimes we need to be sure about have some data before binding theme in Controllers
or Views
or etc, in this case we use resolve to collect all data before rendering them in other place.
If you get nothing in console make sure your URL is correct, in this sample i change
/Menu
to/home
so in url i havelocalhost/#/home
var app = angular.module("dashboard", ["ui.router"]); app.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, urlRouterProvider) { urlRouterProvider.otherwise("home"); $stateProvider.state("home", { url: "/home", templateUrl: "home.html", controller: "dashboardController", resolve: { client: ["service", clientMapResolver], } }); function clientMapResolver(service) { return service.callMe(); } } ]); app.controller("dashboardController", function (client) { console.log(client); }) app.service("service", function () { this.callMe = function () { //var layoutId = $window.parent.parent.parent.location.search.split('=')[1]; var layoutId = "123", return layoutId; } });
Please fill free to question me before voting
Answers 3
Well, your code seems appropriate to me. There are some point which may seem the culprit here, but overall, they shouldn't cause any problem with resolve
.
Below are my observations, as per the existing answers and your code:
Unresolved dependencies
I see that you have only one attribute in resolve
function, i.e. client
. This further depends on 3 components. If any of the dependencies hadn't resolved when resolving client
, there should have been error(s) on the console, which I guess not an issue here because you haven't reported any console errors.
Adding to it, UI router's documentation defines that a simple function in resolve
will be resolved immediately. So, clientMapResolver
should not cause any issue. It is a plain JavaScript function, so UI router will resolve it immediately.
Dangling end comma
Though this is a very small issue, but linters such as JSLint or ESLint can throw an error and prevent compiling of your code in such cases. Watch for related configuration, if any. There is a comma at the end of this line:
client: ['$window', 'dashboardService', 'config', clientMapResolver],
Remove it, and retry.
My suggestions
Since there is not enough information to provide the exact solution, my most probable guess will be to register an error listener for UI router's states, and observe it. UI router broadcasts $stateChangeError
if it encounters any problem with visiting a state.
You can try to listen to it like below:
angular.module("dashboard", [ ... ]) .run(['$rootScope', function($rootScope) { $rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) { console.log(event, toState, toParams, fromState, fromParams); console.error(error); }); }) .config( ... ) // Your other code
This will print a trace of the errored route on the console when there is anything wrong with visiting it.
Answers 4
I agree with @Maher, and there are many unknown details (dependencies
) in the question that makes it hard to debug. I went ahead and simplified the plunkr provided by @31piy to make you understand where the issue is. You say that your resolve function is not working. While your code looks fine, I suspect something wrong in other areas. You can try to remove all dependencies and make it work for a simple scenario and build on from there.
Any idea why resolve is never triggered?
Here is plunkr link that triggers resolve function, with your code. Now go ahead and add your dependencies one by one to know what exactly is causing the issue.
Here is how the simplified code looks like,
(function() { "use strict"; angular.module('dashboard', ['ui.router']) .config(["$stateProvider", function($stateProvider) { var helloState = { name: 'home', url: '/Menu', templateUrl: 'dashboard.tmpl.html', resolve: { client: [clientMapResolver] } } var aboutState = { name: 'about', url: '/about', template: '<h3>Its the UI-Router hello world app!</h3>' } $stateProvider.state(helloState); $stateProvider.state(aboutState); }]).controller('dashboardController', ['$scope', function ($scope) { console.log('Controller activated'); } ]); function clientMapResolver() { alert("I was inside clientMapResolver"); } })();
Here are some links to read more about resolve
so that you can make proper use of them, hope this helps:
Update:
I saw your edit, but still it is difficult to see what might be the cause for resolve
to not fire. Making a wild guess from your code, I can only say that, your resolve function clientMapResolver
gets triggered only when you visit the home
route (url will be /Menu
). I don't see where you are injecting your view (<ui-view></ui-view>
), for that to happen.
Like I said, you should remove/comment out most of the things and check for a base case and build on from there, and please confirm that you have injected your view using <ui-view></ui-view>
, so that your router knows where to inject your view and trigger resolve
.
Answers 5
You can call the function like;
url: "/home", templateUrl: "home.html", controller: "dashboardController", resolve: { fooList: function (fooResolver) { //Your Codes return fooResolver.getList(); } }
If you want Service-Factory may be like this;
app.factory("fooResolver", function () { this.getList= function () { return [{name:"foo"}] } });
0 comments:
Post a Comment