I am a bit confused. I am trying to get my resolve data in my controller. I read about these (and more) solutions, but can not get it working. It is all about the "spages".
http://jsfiddle.net/Avb4U/1/
http://www.jvandemo.com/how-to-resolve-angularjs-resources-with-ui-router/#
Angularjs resolve with controller as string
I hope this is not a duplicate question, because nothing did work for me from these solutions.
This is (part of all states) my state:
.state('root.search', {
url: '/search/:searchterm',
onEnter: ['$rootScope', function($rootScope) {
$rootScope.bodyclass = 'search';
}],
resolve : {
spages: ['$stateParams', 'SearchPages', function($stateParams, SearchPages) {
return SearchPages.get({'searchterm': $stateParams.searchterm});
}]
},
controller: 'searchCtrl',
views: {
'#': {
templateUrl: templateUrlFunction('search')
}
}
})
This is part of my controller:
app.controller('searchCtrl', ['$scope', 'spages', function($scope, spages) {
// spages should be already resolved and injected here
}
And this is my factory for the searchpages:
app.factory('SearchPages', ['$resource', function($resource) {
return $resource(null, {},
{
get: {
method: 'GET',
url: '/json/search/get/searchterm/:searchterm',
params: {searchterm: '#searchterm'}
}
});
}]);
Asfar as i do understand, spages should be resolved and injected in the controller now. But it is not.
The error i get is:
Error: [$injector:unpr] Unknown provider: spagesProvider <- spages
What do i do wrong? I am still learning...
Ok, what i did not realize is that i also have a controller in my template.
And i read: "You only need to specify controller once, in app.js. The second one, in the html code, is instantiated by the ngController directive, which does not know about `resolve', so it throws an exception."
Change your controller dependency from searchpages to SearchPages.
app.controller('searchCtrl', ['$scope', 'SearchPages', function($scope, searchpages) {
// searchpages should be already resolved and injected here
}
Related
I'm having trouble finding what's wrong in my code.
so, i'm resolving an http.get with ui-route and then calling the controller.
Elsewhere it works fine, but in a particular controller it don't
So, in my route.js i have this
.state('post', {
url: '/post/{id}',
templateUrl: 'post.php',
resolve: {
post: ['$http','$stateParams', function($http, $stateParams) {
return $http.get('link' + $stateParams.id)
.then(function(data) {
return data.data; });
}]
},
controller: 'PostController',
})
and the, in my controller i have this:
App.controller('PostController',['$scope', 'post', function PostController($scope, post) {
$scope.posts = post;
}]);
i get as i said an injection problem on post [$injector:unpr] (Unknown provider: postProvider <- post <- PostController), but i can see the http.get data in my controller. What am i missing?
.state('cahonas.static_page', {
url: '*url',
templateUrl: '/static/templates/cahonas/static_pages/static_page.html',
controller: 'StaticPageCtrl',
resolve: {
metaTags: function (metaTagsResource, $stateParams) {
return metaTagsResource.get({
page_name: $stateParams.url.replace("//","")
}).$promise;
},
page: function (staticPageResource, $stateParams) {
return staticPageResource.get({
url: $stateParams.url.replace("//","")
}).$promise;
}
}
.factory('staticPageResource', function($resource) {
return $resource('/api/web/static_page/:url/');
})
this is my code so far. keep bumping into "//" which resolves into error and i cant figure it out. does anyone know about this?
Make sure all of dependency module you include in module declaration point (ngResource and angular-ui-router).
In declaration of factory use strict depedency injection. In configuration area its hard to find problem because it was not throw any error.
app.factroy('staticPageResource', ['$resource', function($resource) {
return $resource('/api/web/static_page/:url/');
}]);
And also try with rename state name by removing .
I face such problem: I have abstract state:
$stateProvider.state('bookings.clients', {
url:"/clients",
abstract:true,
views:{
"#":{
templateUrl:"/Static/CrmPages/CrmMainPage.html",
controller:"CrmMainPageController",
}
},
resolve: {
clientsData:function(clientsDataService) {
return clientsDataService.loadData('ihor.korotenko#n-cube.co.uk');
},
clientsGroupsData: function (userGroupsService) {
//return "some";
return userGroupsService.api.query(function (data) {
userGroupsService.data = data;
}).$promise;
}
}
});
As you can see there are two resolve objects.
Than, I inject this objects to controller in child state:
angular.module("crmModule")
.controller("mainPageController", ['clientsGroupsData', 'clientsData', "$scope", "$rootScope", "$translate", 'clients', 'cultureProvider', '$state', function (clientsGroupsData, clientsData, $scope, $rootScope, $translate, clients, cultureProvider, $state)
My resource provider:
angular.module("crmModule")
.service("userGroupsService", ['$resource', function ($resource) {
var self = this;
self.data = [];
return {
api: $resource("/api/groupsapi/getallgroups"),
data: self.data
}
}])
Child state:
$stateProvider.state('bookings.clients.overview', {
url:"/overview",
views:{
"crm.main":{
templateUrl: "/Static/CrmPages/main-page.html",
controller:"mainPageController"
}
},
});
The problem is following: when controller instantiates I see that injected object is not empty and resolved(It`s ok), but after that I get an exception
Error: [$injector:unpr] Unknown provider: clientsGroupsDataProvider <- clientsGroupsData <- mainPageController
How can I fix this?
So I found the reason of this error, it occurs because I attach controller in html via ng-controller directive, and of course, ui-router can`t inject dependency because it doesnt intantiate controller.
I have a api that i want to resolve name for "bubble". This i would like to inject into controller - but problem is that i have tried different approaches and all just say...undefined and some injection problems... :(
Code:
.state('bubbles', {
abstract: false,
url: "/bubbles/:bubbleId/feed",
controller: 'BubblesController',
data: {
authorizedRoles: [USER_ROLES.editor]
},
resolve: {
resolvedBubbleName: function ($http, $stateParams) {
var url = 'https://XXXXXXX.net/api/Bubble/11111111-1111-1111-1111-111111111111';
return $http.get(url)
.then(function (response) {
console.log('response ' + response);
return response;
});
},
views: {
'navigation': {
templateUrl: "/raqt/shared/partials/navigation.html"
},
'main': {
templateUrl: "/raqt/bubbles/partials/bubbles.html"
//controller: function ($scope, resolvedBubbleName) {
// $scope.resolvedBubbleName = resolvedBubbleName;
// // resolvedBubbleName is always undefined, i.e.,
// // UI router is not injecting it
//}
}
},
}
})
In my controller i tried different approaches and this that i think should work... gives error injection...
BubblesController.$inject = ['$stateParams', '$state', '$log', '$timeout', '$interval', '$scope', 'BubblesService', 'CONFIG', '$http', 'resolvedBubbleName'];
function BubblesController($stateParams, $state, $log, $timeout, $interval, $scope, BubblesService, CONFIG, $http, resolvedBubbleName) {
$scope.title = 'bubbles-controller';
alert(resolvedBubbleName);
$scope.bubbleId = $state.params.bubbleId;
Error from page
Error: [$injector:unpr] Unknown provider: resolvedBubbleNameProvider <- resolvedBubbleName <- BubblesController
http://errors.angularjs.org/1.3.15/$injector/unpr?p0=resolvedBubbleNameProvider%20%3C-%20resolvedBubbleName%20%3C-%20BubblesController
at REGEX_STRING_REGEXP (http://localhost:3604/js/lib/angular/angular.js:63:12)
at http://localhost:3604/js/lib/angular/angular.js:4015:19
at Object.getService [as get] (http://localhost:3604/js/lib/angular/angular.js:4162:39)
at http://localhost:3604/js/lib/angular/angular.js:4020:45
at getService (http://localhost:3604/js/lib/angular/angular.js:4162:39)
at Object.invoke (http://localhost:3604/js/lib/angular/angular.js:4194:13)
at $get.extend.instance (http://localhost:3604/js/lib/angular/angular.js:8493:21)
at http://localhost:3604/js/lib/angular/angular.js:7739:13
at forEach (http://localhost:3604/js/lib/angular/angular.js:331:20)
at nodeLinkFn (http://localhost:3604/js/lib/angular/angular.js:7738:11) <div ui-view="main" class="ng-scope">
I can see that $http call is having data and i know controller works well otherwise - but this resolve driving me mad.. :(
I will be off for couple of hours - but i WILL ge back to this if you see some problems in my code i will ge back and answer!... :)
I would say, that you've wrongly nested views : {} into the resolve : {}. There is a working plunker
I just moved your definitions into correct positions and it is working
.state('bubbles', {
abstract: false,
url: "/bubbles/:bubbleId/feed",
//controller: 'BubblesController',
data: {
authorizedRoles: [{}], //USER_ROLES.editor]
},
resolve: {
resolvedBubbleName: ['$http', '$stateParams',
function($http, $stateParams) {
//var url = 'https://XXXXXXX.net/api/Bubble/11111111-1111-1...';
var url = 'someData.json'
return $http.get(url)
.then(function(response) {
console.log('response ' + response);
return response.data;
});
}
],
},
views: {
'navigation': {
templateUrl: "raqt/shared/partials/navigation.html",
controller: 'BubblesController',
},
'main': {
templateUrl: "raqt/bubbles/partials/bubbles.html",
controller: ['$scope', 'resolvedBubbleName',
function($scope, resolvedBubbleName) {
$scope.resolvedBubbleName = resolvedBubbleName;
}
]
}
},
})
Also, one very important note:
controller belongs to view - not to state
You can read more here:
Are there different ways of declaring the controller associated with an Angular UI Router state
Check the working example here
EXTEND
In case, that we adjusted all the code as above and we are provided with this error:
Error: [$injector:unpr] Unknown provider: resolvedBubbleNameProvider <- resolvedBubbleName <- BubblesController
We are most likely in one of these scenarios:
we have elsewhere in our state hierarchy reused the "BubblesController", while not having resolve : { 'resolvedBubbleName': ... } in place
we declared somewhere ng-controller="BubblesController" - which is not managed by UI-Router. And it does not have access to so called locals (containing resolved values)
so, be sure where is the controller defined - all will start working then...
I want to resolve some value before I load the first page of my application, but it kept telling me
Unknown provider: programClassSummaryProvider <- programClassSummary <- HomeCtrl
I pretty sure I did it correctly, because I did the same thing for any other controller and routing. but it is not working for my homepage controller.
It seems like it load the controller first, before it is resolved in the routing. Anything wrong with my code?
In routing.js
$stateProvider
.state('home', {
url: '/home',
controller: 'HomeCtrl',
controllerAs: 'vm',
templateUrl: 'index_main.html',
resolve: {
programClassSummary: ['GroupDataFactory', function (groupDf) {
return groupDf.getProgramClassSummary();
}]
},
ncyBreadcrumb: {
skip: true
}
});
in controller.js
angular
.module('issMccApp')
.controller('HomeCtrl', homeCtrl);
homeCtrl.$inject = ['$scope', '$location', '$state', '$auth', 'programClassSummary'];
/* #ngInject */
function homeCtrl($scope, $location, $state, $auth, programClassSummary) {
var vm = this;
vm.isAuthenticated = isAuthenticated;
vm.programClassSummary = programClassSummary;
if (!$auth.isAuthenticated()) {
$state.go('login');
return;
}
function isAuthenticated() {
return $auth.isAuthenticated();
}
}
in factory.js
function getProgramClassSummary(showAll) {
var query = "";
if (showAll)
query = APIConfigObj.base_url + '/api/group/infor/programclasssummary?all=1';
else
query = APIConfigObj.base_url + '/api/group/infor/programclasssummary';
return $http.get(query)
.success(function (result) {
return result;
})
.error(function (err) {
return err;
})
}
I'd say, we really have to distinguish the UI-Router state world, and angular itself. Reason why is clearly defined here (extracted $resolve from UI-Router API documentation):
$resolve
resolve(invocables, locals, parent, self)
Resolves a set of invocables. An invocable is a function to be invoked via $injector.invoke(), and can have an arbitrary number of dependencies. An invocable can either return a value directly, or a $q promise. If a promise is returned it will be resolved and the resulting value will be used instead. Dependencies of invocables are resolved (in this order of precedence)
from the specified locals
from another invocable that is part of this $resolve call
from an invocable that is inherited from a parent call to $resolve (or recursively
from any ancestor $resolve of that parent).
There is a wroking plunker, which uses this index.html
<body ng-controller="RootCtrl">
a summary for a root:
<pre>{{summary}}</pre>
<ul>
<li>home
<li>other
</ul>
<div ui-view=""></div>
So, here we use some RootCtrl, which won't go through state machine UI-Router, it is angular basic stuff
The root controller must be defined as
.controller('RootCtrl', ['$scope', 'GroupDataFactory', function ($scope, groupDf) {
$scope.summary = groupDf.getProgramClassSummary();
}])
For a state home, we can use different approach, in fact the same as above (simplifed version below)
.state('home', {
url: "/home",
templateUrl: 'tpl.home.html',
resolve: {
programClassSummary: ['GroupDataFactory', function (groupDf) {
return groupDf.getProgramClassSummary();
}]
},
controller: 'HomeCtrl',
})
And its controller is now able to consume the locals
.controller('HomeCtrl', ['$scope', 'programClassSummary', function ($scope, summary) {
$scope.summaryForHome = summary;
}])
Check it in action here