Angular ui-router resolve not working - angularjs

I am trying to load a get service JSON function in the main state resolve function so I can store the data to a scope variable.
The account JSON information is relevant because all sub pages are essentially dependent on the information.
--
The below code is partially working. The account resolve function is being successfully called and even the $http returns a promise (state === 0 though). The issue is when the account function resolves the state.controller is never being called.
$stateProvider
.state('app',{
url: '/',
views: {
'header': {
templateUrl: '../views/templates/partials/header.html',
},
'content': {
templateUrl: '../views/templates/partials/content.html'
},
'footer': {
templateUrl: '../views/templates/partials/footer.html',
}
},
resolve: {
account: function($timeout, accountFactory){
//Comment
return $http({method: 'GET', url: '/account.json'});
}
},
controller: ['$scope', 'account', function($scope, account){
// You can be sure that promiseObj is ready to use!
$scope.data = account;
console.log('SCOPE!!!!!');
}],
})
.state('app.accessory', {
url: 'accessory',
views: {
'content#': {
templateUrl: '../views/accessory/listing.html',
controller: 'accessoryListingCtrl',
controllerAs: 'vm'
}
}
})
}]);

Your parent state config is not correct. When using multiple named views A controller does not belong to a state but to a view, so you should move your controller statement to the specific view declaration, or all of them if you need it everywhere.
See here: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
$stateProvider
.state('report',{
views: {
'filters': {
templateUrl: 'report-filters.html',
controller: function($scope){ ... controller stuff just for filters view ... }
},
'tabledata': {
templateUrl: 'report-table.html',
controller: function($scope){ ... controller stuff just for tabledata view ... }
},
'graph': {
templateUrl: 'report-graph.html',
controller: function($scope){ ... controller stuff just for graph view ... }
},
}
})

I don't know why the controller does not get called. But you can start by making sure that resolve always return data.
resolve: {
account: function($timeout, accountFactory){
//Comment
return $http({method: 'GET', url: '/account.json'})
.$promise.then(
function(data) { return data; },
function(error) { return error; });
}
}

Related

Using resolve functions once in angular js and angular router to few controllers

Ui router looks like:
<div ui-view="test1">
<div ui-view="test2">
My routing:
.state('testsPage', {
url: "/",
// templateUrl: "public/src/settings/settings.php",
views: {
'test1': {
templateUrl: 'public/src/test2.html',
controller: 'test2Controller',
controllerAs: 'vm',
resolve: {
getData: function(testService) {
return testService.getdata();
}
}
},
'test2': {
templateUrl: 'public/src/test1.html',
controller: 'test1ontroller',
controllerAs: 'vm',
resolve: {
getData: function(testService) {
return testService.getdata();
}
}
},
I want to call getData only once and not inject it the each controller
If I do that in each controller it means that I call to getData from server two times in loading.
I tried to use controller inheritance but it ask to inject that service
// Inherit from Base Controller
angular.extend(vm, $controller('baseController', {
getData: getData,
testService: testService,
$rootScope: $rootScope
}));
How can I make it like inheritance?
Do I need to move it to run the function? If yes do I have to use rootScope to get that data in the controller?
Try putting the resolve on the parent:
.state('testsPage', {
url: '/',
views: ...,
resolve: {
getData: function(testService) {
return testService.getdata();
}
}
...
}
You would then need to add getData as a dependancy on each views controller:
// Controller
function test1ontroller(getData) {
}

$state.params and $stateParams passing data

I've read many posts but none of them work:
I want to pass some data using $state.go.
this is my state :
.state('app.404', {
url: '404',
views: {
'header#': {
templateUrl: 'views/empty.html'
},
'content#': {
templateUrl: '404.html',
controller: 'fofController'
},
'footer#': {
templateUrl: 'views/empty.html'
},
params: {errorInfo: null}
}
})
this is how I pass the data :
$state.go('app.404', {errorInfo: {status: 403, message: 'unauthorised', fix: 'You have to login'}});
and this is how I try to catch the data in my controller:
.controller('fofController', ['$scope', '$state',
function ($scope, $state) {
console.log($state.params);
}])
but the answer is an empty object ({}). I also used $stateParams like below but I get the same result, an empty object:
.controller('fofController', ['$scope', '$stateParams',
function ($scope, $stateParams) {
console.log($stateParams);
}])
option -1
.state('404.contact/', {
url: '/contact/:obj',
templateUrl: "contact.html",
controller: "contactCtrl",
params: {
obj: null,
}
})
.state('404.header', {
url: '/header/:number',
templateUrl: "header.html",
controller: "headerCtrl",
params: {
obj: null
}
})
option-2
$state.go(.....
You should try this code instead
$state.transitionTo(...
option-3
Perhaps try transferring with url
$stateProvider
.state('user', {
url: '/user/:obj',
templateUrl: 'templates/user.html',
controller: 'UserCont'
})
Maybe these are the solution to the problem.
Working example with $state.go()

Passing resolved data to child state in Ui-Router

So, I have a state where the resolve spits out an array which shows correctly on the frontend.
But I can't seem to be able to pass the parent resolve data to the child state.
$stateProvider.state('berliner', {
url: '/berlinerliste',
params : {search: 'Berliner 2017'},
resolve: {
fair: function(SearchService, $stateParams) {
return SearchService.getAllExhibitors($stateParams.search);
}
},
views: {
'header': {
templateUrl: 'header.htm'
},
'main':{
templateUrl: 'bl2017.htm',
controller: function($scope, fair){
$scope.fair = fair;
console.log($scope.fair);
}
}
}
})
.state('berliner.exhibitor', {
url: '/{id}',
resolve: {
exhibitor: function($stateParams, fair) {
var slug = $stateParams.id;
return slug;
}
},
views: {
'header': {
templateUrl: 'header.htm'
},
'wop':{
templateUrl: 'exhibitor.htm',
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
}
}
})
All the console log come out undefined.
What am I missing?
PLUNKR
Here's a Plunkr to examplify the issue.
I would say, that the concept should work.. just:
controller belongs to view. not to all views: {}
E.g. this (wrong)
// each view can have controller,
// but views : {} property 'controller' is not used at all
views: {
'header': {
templateUrl: 'header.htm'
},
'wop':{
templateUrl: 'exhibitor.htm',
},
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
should be adjusted as that:
views: {
'header': {
templateUrl: 'header.htm'
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
},
'wop':{
templateUrl: 'exhibitor.htm',
controller: ...
There is an example, how
parent does resolve
child view's controller consumes it
states:
.state('parent', {
url: "/parent",
templateUrl: 'tpl.html',
resolve: {
example: ['$timeout', function($timeout){
return $timeout(function(){
return {x: 1}
},100)
}],
},
})
.state('parent.child', {
url: "/child",
templateUrl: 'tpl.html',
controller: 'ChildCtrl',
})
child controller
.controller('ChildCtrl', ['$scope', 'example', function ($scope, example) {
console.log(JSON.stringify(example));
}])
Check it here

$stateParams is getting empty value even though route has parameters

I am hitting this url
http://localhost:8001/#/verifyMail?4c4e77a2
at that time i did
console.log($stateParams);
It shows empty object
My route is
.state('mailVerification', {
url: "/verifyMail?id",
templateUrl: "app/views/common/emailVerification.html",
controller: 'accountCtrl',
data: {
authorizedRoles: [USER_ROLES.all]
}
})
Why i am not getting $stateParams.id value? Please help me.
You need to resolve the data.
.state('mailVerification', {
url: "/verifyMail?id",
templateUrl: "app/views/common/emailVerification.html",
resolve: {
id: function($stateParams){
return $stateParams.id;
}
}
controller: 'accountCtrl',
data: {
authorizedRoles: [USER_ROLES.all]
}
})
and inside the controller:
.controller('accountCtrl', ['id', '$log', function(id, $log){
$log.debug(id);
}]);

How to map a segment of a route to routeParams?

Lets say I have two routes defined, served by the same view and controller, such as
/customers/:cutomerId/edit
/customers/add
in a controller I need to determine in which "mode" is view in. How do I map "edit" and "add" segments of the route so that it appears in $routeParams. Is there a way?
You may user route's resolves to solve it.
For example:
myApp.config(function($routeProvider) {
$routeProvider
.when('/customers/:cutomerId/edit', {
templateUrl: 'myView.html',
controller: 'MyController',
resolve: {
mode: function() {
return 'edit';
}
}
})
.when('/customers/add', {
templateUrl: 'myView.html',
controller: 'MyController',
resolve: {
mode: function() {
return 'add';
}
}
});
myApp.controller('MyController', function($scope, mode){
// Now controller knows it's mode.
});

Resources