I have got a ui -router state here
var AccountParentState = {
url: "/Account",
views: accountrootview,
stickA: true,
},
AccountAddState = {
url: "/add",
views: addaccountview,
controller: "account-controller",
resolve: {
Name: function () {
return "Joydeep";
}
}
};
$stateProvider
.state('account', AccountParentState)
.state("account.add", AccountAddState)
And this is my controller :
angular.module('ngApp').controller('account-controller', ['$scope', '$state', "account", "plugin-factory", "Name", function ($scope
, $state
, account
, plugins, Name) {
console.log(Name);
}]);
When I am trying to resolve the Name within the account-controller . Its throwing the error as :
Unknown provider: NameProvider <- Name <- account-controller
My question is how to resolve this situation . Or resolve the data within the ui-router state using resolve property .
To help you to see the issue, I created working plunker, which does use similar definition to the above states:
var AccountParentState = {
url: "/Account",
views: { '' :
{ template: 'Account state <hr/><div ui-view=""></div>',} },
stickA: true,
},
AccountAddState = {
url: "/add",
//views: addaccountview,
templateUrl: 'tpl.html',
controller: "account-controller",
resolve: {
Name: function() {
return "Joydeep";
}
}
};
$stateProvider
.state('account', AccountParentState)
.state("account.add", AccountAddState)
Factories and controller:
.factory('account', function(){return {}})
.factory('plugin-factory', function(){return {}})
.controller('account-controller',
['$scope', '$state', "account", "plugin-factory", "Name"
, function($scope, $state, account, plugins, Name) {
console.log(Name);
}
])
And that is working, because controller was instantiated by the UI-Router, as a part of the state transition.
If, on the other hand, we will extend that example with this (see forked broken version) line in the index.html (outside of the state def)
<div ng-controller="account-controller"></div>
<div ui-view=""></div>
The issue will appear. Why? Because now the controller is not managed by the UI-Router. It is not injected by its infrastructure, not provided with configured value 'Name'. It is "plain angular" style..
Check the working solution here and the broken here
Related
I've upgraded my version of Angular to 1.7.8 and also upgraded angular-ui-router to 1.0.22.
After upgrade my resolved data from the router configuration isn't working (anymore).
Route configuration:
$stateProvider.state('app', {
views: {
'#' : {
templateUrl: CONFIG.BasePath + '/article/views/layout.html'
},
'article#app': {
templateUrl: CONFIG.BasePath + '/article/views/index.html',
controller: 'ArticleController',
resolve : {
settings: function() {
return {
someValue: ''
};
},
deps: ['$ocLazyLoad', function($ocLazyLoad) {
// other code
}]
}
}
}})
Controller:
function MapController ($scope, settings) {
console.log(settings);
}
MapController.$inject = [
'$scope',
'settings'
];
When I try to access it from the resolves object, it works, but this is not the way to go imho...
function MapController ($scope) {
console.log($scope.myResolves.$state$.views['article#app'].resolve.settings());
}
MapController.$inject = [
'$scope'
]
ui-router 1.0 does not support resolve into views:
We no longer process resolve blocks that are declared inside a views.
you need to rewrite it and move resolves out to a resolve block on the state:
Now, move all resolves out to a resolve block on the state:
Read here for more details and examples: ui-router
I am trying to adapt to Angular's component (from code generated by Angular Fullstack Generator).
I tried to configure the routes to resolve "query" as per below:
angular.module('paizaApp')
.config(function($stateProvider) {
$stateProvider
.state('main', {
url: '/',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function(){return null;}
},
.state('starred',{
url:'/users/:userId/starred',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function($stateParams){
return {stars:$stateParams.userId};
}
}
})
.state('users',{
url:'/users/:userId',
template: '<main query="$resolve.query"></main>',
resolve:{
query:function($stateParams){
return {user:$stateParams.userId}
}
}
The following are the codes for the controller/component.
class MainController {
constructor($http, $scope, socket, Auth, query) {
this.$http = $http;
this.socket = socket;
this.awesomeThings = [];
$scope.isLoggedIn = Auth.isLoggedIn;
$scope.getCurrentUser = Auth.getCurrentUser;
$onInit() {
this.$http.get('/api/things',{params:{query:query}})
.then(response => {
this.awesomeThings = response.data;
this.socket.syncUpdates('thing', this.awesomeThings);
});
}////////
////////////////////////////////////// etc..
angular.module('paizaApp')
.component('main', {
templateUrl: 'app/main/main.html',
bindings:{query:'='},
controller: MainController
});
I am getting an error message - unknown query provider. However if I remove query from the constructor then the error message is "query is not defined".
Can you please see where I have gone wrong and whether I am supposed to inject the "query" variable into the controller? I am new to Angular 1, not to mention Angular 2.
Update: I have also tried something like this but didn't work:
angular.module('paizaApp')
.config(function($stateProvider) {
$stateProvider
.state('main', {
url: '/',
template: '<main></main>',
resolve:{
query:function(){return null;}
},
controller:function($scope,query){
$scope.query=query
}
And:
angular.module('paizaApp')
.component('main', {
templateUrl: 'app/main/main.html',
controller: MainController,
scope:{query:'='}
});
You shouldn't inject query on controller constructor. You could have do that if you have specified MyController as controller for state.
The query resolve is already passed in component bindings. You can directly get the value of query resolve inside this.query
I'm losing my mind trying to figure out why the following code produces an Unknown Provider error "geonameProvider <- geoname <- country"
var cacRouteViewMod = angular.module('cacRouteViewMod', ['ngRoute', 'cacLib']);
cacRouteViewMod.config(['$routeProvider', function($routeProvider, $routeParams) {
$routeProvider
.when('/countries/:country/capital', {
templateUrl: 'countries/country.html',
controller: 'countryDetailCtrl',
resolve: {
geoname: ['$route', 'getGeoname', function($route, getGeoname) {
return getGeoname($route.current.params.country);
}],
country: ['getCountry', 'geoname', function(getCountry, geoname) {
return getCountry(geoname.countryCode);
}],
neighbors: ['$route', 'getNeighbors', function($route, getNeighbors) {
return getNeighbors($route.current.params.country);
}]
}
})
});
I've seen some codes where almost identical code is given as a working example. Like this other stackoverflow post (Angular JS resolve in a resolve).
And this article (https://medium.com/opinionated-angularjs/advanced-routing-and-resolves-a2fcbf874a1c).
Why won't mine work?
I believe it's because you are using ngRoute (the native routing module in AngularJS) instead of ui-routeur (the module referred in your articles)
Try using ui-router instead, it should looks like:
.state('countries', {
url: "/countries/:country/capital",
templateUrl: 'countries/country.html',
controller: 'countryDetailCtrl',
resolve: {
geoname: ['$route', 'getGeoname', function($route, getGeoname) {
return getGeoname($route.current.params.country);
}],
country: ['getCountry', 'geoname', function(getCountry, geoname) {
return getCountry(geoname.countryCode);
}],
neighbors: ['$route', 'getNeighbors', function($route, getNeighbors) {
return getNeighbors($route.current.params.country);
}]
})
});
And inject it as a dependency :
var cacRouteViewMod = angular.module('cacRouteViewMod', ['ui-router', 'cacLib']);
I have a state with resolve:
function config($stateProvider, $urlRouterProvider) {
$stateProvider
.state('emails.list', {
url: "/list/:folder/:page",
parent: 'emails',
templateUrl: "views/emails.list.html",
data: { pageTitle: 'Mail Inbox' },
resolve: {
searchResult: ['Emails', function (Emails) {
return 1;
}]
}
});
}
And I have a controller for this state:
function EmailListCtrl($scope, searchResult, $stateParams, $state) {
...
}
angular.module('peachy').controller('EmailListCtrl', EmailListCtrl);
When I try to pass searchResult to controller I get an error [$injector:unpr]. How it can be fixed? (Or may be something wrong in configuration)
Angular version is 1.3.6
My mistake:
I called EmailListCtrl using ng-controller. Right way is setting controller name in state:
function config($stateProvider, $urlRouterProvider) {
$stateProvider
.state('emails.list', {
...
controller: 'EmailListCtrl'
});
}
There is a working plunker. Try to be sure that even EmailListCtrl recives all the needed dependencies properly:
function EmailListCtrl($scope, result, $stateParams, $state) {
$scope.data = { searchResult : result };
};
EmailListCtrl.$inject = ['$scope','searchResult','$stateParams','$state'];
the $inject contains clear definition for angluar IoC ... so I could even use result as param name instead of searchResult
Check it here
So consider the following fragment from my angularUI routing setup. I am navigating to the route /category/manage/4/details (for example). I expect 'category' to be resolved before the relevant controller loads, and indeed it is to the extent that I can put a breakpoint inside the resolve function that returns the category from the category service and see that the category has been returned. Now putting another breakpoint inside the controller itself I can see that 'category' is always undefined. It is not injected by UI router.
Can anyone see the problem? It may be somewhere other than in the code I've provided but as I have no errors when I run the code, it's impossible to tell where the source of the issue might lie. Typical js silent failures!
.state('category.manage', {
url: '/manage',
templateUrl: '/main/category/tree',
controller: 'CategoryCtrl'
})
.state('category.manage.view', {
abstract: true,
url: '/{categoryId:[0-9]*}',
resolve: {
category: ['CategoryService', '$stateParams', function (CategoryService, $stateParams) {
return CategoryService.getCategory($stateParams.categoryId).then(returnData); //this line runs before the controller is instantiated
}]
},
views: {
'category-content': {
templateUrl: '/main/category/ribbon',
controller: ['$scope', 'category', function ($scope, category) {
$scope.category = category; //category is always undefined, i.e., UI router is not injecting it
}]
}
},
})
.state('category.manage.view.details', {
url: '/details',
data: { mode: 'view' },
templateUrl: '/main/category/details',
controller: 'CategoryDetailsCtrl as details'
})
The concept is working. I created working plunker here. The changes is here
instead of this
resolve: {
category: ['CategoryService', '$stateParams', function (CategoryService, $stateParams) {
//this line runs before the controller is instantiated
return CategoryService.getCategory($stateParams.categoryId).then(returnData);
}]
},
I just returned the result of the getCategory...
resolve: {
category: ['CategoryService', '$stateParams', function (CategoryService, $stateParams) {
return CategoryService.getCategory($stateParams.categoryId); // not then
}]
},
with naive service implementation:
.factory('CategoryService', function() {return {
getCategory : function(id){
return { category : 'SuperClass', categoryId: id };
}
}});
even if that would be a promise... resolve will wait until it is processed...
.factory('CategoryService', function($timeout) {return {
getCategory : function(id){
return $timeout(function() {
return { category : 'SuperClass', categoryId: id };
}, 500);
}
}});