Angular UI Router - Access Custom Data in Children's Resolve {} - angularjs

How come this Inherited Custom Data data is not accessible in the child state main.loadbalancer.vips in the resolve: {} function hello?
angular.module("main.loadbalancer", ["ui.bootstrap", "ui.router"]).config(function($stateProvider) {
return $stateProvider.state("main.loadbalancer", {
data: { readonly : false },
url: "device/:id",
views: {
"content#": {
templateUrl: "loadbalancer/loadbalancer.html",
controller: "LoadBalancerCtrl"
}
}
}).state("main.loadbalancer.vips", {
url: "/vips",
templateUrl: "loadbalancer/vip-table.html",
resolve: {
hello: function(data) {
console.log(data);
}
},
controller: "VipListCtrl"
})

That data should be accessible in the $state object if you inject it ($state):
$state.$current.data.readonly

I had to use this.data...
}).state("main.loadbalancer.vips", {
url: "/vips",
templateUrl: "loadbalancer/vip-table.html",
resolve: {
hello: function() {
console.log(this.data);
}
}

Related

How do I get URL parameters on AngularJS SPA when using stateProvider for routing

For example, on the last state on the below code I want to get the value of "category" URL parameter so that I can use it to retrieve some from the database
var app = angular.module("myApp",["ui.router"]);
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/");
$stateProvider
.state("main", {
url: "/",
views: {
"slider": {
templateUrl: "slider.html"
},
"departments": {
templateUrl: "departments.html"
},
"brands": {
templateUrl: "brands.html"
}
}
})
.state("cart", {
url: "/cart",
views: {
"cart": {
templateUrl: "../account/cart.php"
}
}
})
.state("department", {
url: "/department/:category",
views: {
"department": {
templateUrl: "department.php"
}
}
});
});
Create a controller, pass stateParams and instantiate the controller within the views of the last state
.state("department", {
url: "/department/:category",
views: {
"department": {
templateUrl: "department.php",
controller: "myController"
}
}
});
});
app.controller('myController', function($stateParams) {
var param = $stateParams.category;
document.getElementById("category").value = param;
});

AngularJS uiRouter access controller from other view

I have simple hierarchical state:
angular
.module('App.Module.Suppliers', [])
.config(function($stateProvider) {
return $stateProvider
.state('suppliers', {
url: '/suppliers',
views: {
main: {
templateUrl: 'views/layouts/wrapper.html'
}
}
})
.state('suppliers.edit', {
url: '/:id',
views: {
entity_view: {
templateUrl: 'views/layouts/foo.html'
}
}
})
.state('suppliers.edit.details', {
url: '/edit',
views: {
entity_sub_view: {
controller: function () {
this.foo = {bar: "TEST HEADER"};
},
controllerAs: 'vm',
templateUrl: 'views/layouts/main.html'
}
}
});
});
main and entity_view views are generic for all entities and only entity_sub_view changes with core information.
Now in entity_view I want to use some value like <h2>{{vm.foo.bar}}</h2> but it seems that I can't access vm inside these parent states.
Is there a way to pass this and other parameters to parent states to use?
So I found solution that fits my need. Basically you can set controllerAs to top-most state and access it via $scope:
angular
.module('App.Module.Suppliers', [])
.config(function($stateProvider) {
return $stateProvider
.state('suppliers', {
url: '/suppliers',
views: {
main: {
templateUrl: 'views/layouts/wrapper.html'
controller: function () {
this.foo = null;
}
controllerAs: 'mainCtrl'
}
}
})
.state('suppliers.edit', {
url: '/:id',
views: {
entity_view: {
templateUrl: 'views/layouts/foo.html'
}
}
})
.state('suppliers.edit.details', {
url: '/edit',
views: {
entity_sub_view: {
controller: function () {
this.foo = {bar: "TEST HEADER"};
},
controllerAs: 'vm',
templateUrl: 'views/layouts/main.html'
}
}
});
});
And in some controller do
this.$scope.mainCtrl.foo = {bar: "TEST HEADER"};
In view
{{mainCtrl.foo.bar}}

How to modify url of a state in AngularJS ui-routes

I am on angular 1.6. Trying to override value of a ui-router state.
Initial states as follows :
$stateProvider.state('parent', {
abstract: true,
parent: 'ancestor',
url: '/parent',
data: {
authorities: [A,B]
},
views: {
'content#': {
templateUrl: 'app/scripts/myapp/module/parent.html'
}
}
})
.state('child', {
parent: 'parent',
abstract: true,
views: {
'tabs': {
templateUrl: 'app/scripts/myapp/module/submodule/child.html',
controller: 'ChildController',
controllerAs: 'childController'
}
}
})
.state('grandChild', {
parent: 'child',
url: '/{dataSource:(?:option1|option2|option3)}',
views: {
'body': {
templateUrl: 'app/scripts/myapp/module/submodule/grandchild.html',
controller: 'GrandChildController',
controllerAs: 'grandChildController'
},
},
resolve: {
groups: ['MyService', '$transition$', function (MyService, $transition$) {
var selectedSource = $transition$.params().dataSource ? $transition$.params().dataSource : 'option1';
return MyService.getGroups(selectedSource);
}]
}
})
Then in one of sub-implementation I am trying to override value of url - adding option4 for one of the state.
var states = $stateRegistry.deregister('grandChild');
$stateRegistry.register(states[0]);//There is one more child. For simplicity not showing here.
states[1].url.pattern = '/{dataSource:(?:option1|option2|option3|option4)}';
$stateRegistry.register(states[1]);
when I do following on 'grandChild'
$state.go('grandChild', {dataSource: 'option4'});
I get error as
Param values not valid for state 'grandChild'. Invalid params: [ dataSource ]
when I inspect $state
I see something weird.
$state.$current.params.datasource.type.pattern = /(?:option1|option2|option3)/
$state.$current.url.pattern = "/{dataSource:(?:option1|option2|option3|option4)}"
$state.$current.url._compiled[0] = /((?:option1|option2|option3))/

can resolve or anything be used inside the views section of state in $stateprovider in ui-router to pass a specific data to controller of angularjs

I have a requirement to get a specific data into the controller which is present inside views section of the state of the $stateProvider of ui-router
state('main', {
abstract: true
url: "/main"
controller: 'MainController'
templateUrl: "main.html"
})
.state('main.state1', {
url: "",
views: {
'view1': {
resolve: function() {
return {
configuration: "widget1"
};
},
templateUrl: "sample1.html",
controller: 'Controller1'
},
'view2': {
resolve: function() {
return {
configuration: "widget2"
};
},
templateUrl: "sample2.html",
controller: 'Controller2'
},
'view3': {
resolve: function() {
return {
configuration: "widget3"
};
},
templateUrl: "sample3.html",
controller: 'Controller3'
},
'view4': {
resolve: function() {
return {
configuration: "widget4"
};
},
templateUrl: "sampl4.html",
controller: 'Controller4'
}
}
});
Now my question will this code work for give the following result
controller1 in the above gets the value of configuration as widget1
controller2 in the above gets the value of configuration as widget2
controller3 in the above gets the value of configuration as widget3
controller4 in the above gets the value of configuration as widget4
if this is not possible then How can I pass the value to the individual controllers
My main.html file looks like this
<div class="main-column">
<div class="detail-container">
<h2>{{pageTitle | translate}}</h2>
</div>
<div class="grid grid-flex">
<div autoscroll="false" ui-view="view1"></div>
<div autoscroll="false" ui-view="view2"></div>
<div autoscroll="false" ui-view="view3"></div>
<div autoscroll="false" ui-view="view4"></div>
</div>
</div>
if you just need to pass a data, dont need a resolve then do like this
.state('state1', {
url: 'url',
templateUrl: 'views/misc/profile.html',
controller: 'profileController',
data: {
configuration: 'widget'
}
});
If you need resolve then try this.
state('state1', {
url: "url.html",
views: {
'view1': {
resolve: {
configuration: function() {
return "widget1";
}
},
templateUrl: "sample1.html",
controller: 'Controller1'
},
'view2': {
resolve: {
configuration: function() {
return "widget2";
}
},
templateUrl: "sample2.html",
controller: 'Controller2'
},
'view3': {
resolve: {
configuration: function() {
return "widget3";
}
},
templateUrl: "sample3.html",
controller: 'Controller3'
},
'view4': {
resolve: {
configuration: function() {
return "widget4";
}
},
templateUrl: "sampl4.html",
controller: 'Controller4'
}
}
});

Joining add and edit in one route

I'm wondering weather I can join two routes into one - add and edit.
Here are my states:
.state('app.topics.add', {
url: 'add/',
views: {
'page#app': {
templateUrl: 'app/sites/topics/add.html',
controller: 'topicsaddCtrl'
}
}
})
.state('app.topics.details', {
url: '{topic_id:[0-9]+}/',
views: {
'page#app': {
templateUrl: 'app/sites/topics/details.html',
controller: 'topicsdetailsCtrl'
}
}
})
.state('app.topics.details.edit', {
url: 'edit/',
views: {
'page#app': {
templateUrl: 'app/sites/topics/add.html',
controller: 'topicsaddCtrl',
}
}
})
topic/add/ - adding topic
topic/2/ - details of topic
topic/2/edit/ - editing topic
But state for add and edit are using the same templates and controllers. Can I simplyfy states?
You can use stateParams https://github.com/angular-ui/ui-router/wiki/URL-Routing
.state('app.topics.add', {
url: ':method/:id',
views: {
'page#app': {
templateUrl: 'app/sites/topics/add.html',
controller: 'topicsaddCtrl',
}
},
resolve: {
formData: ['$stateParams', 'topicSvc', function ($stateParams, topicSvc) {
if ($stateParams.method === 'add') {
return {}; //return empty object if you creating topic
} else if ($stateParams.method === 'edit' && $stateParams.id) {
return topicSvc.getDetail($stateParams.id); //get topic data from topicSvc service
}
}]
}
})
Also you can inject $stateParams to your controller and access its 'method' and 'id' property.

Resources