I'm trying to pass an object with $state.go() to another state , but the $stateParams is not getting populated .
I have tried everything I could find on web and stackoverflow , but none worked for me. thanks in advance for your help.
here is the code :
MyApp.config(function($stateProvider, $urlRouterProvider){
$stateProvider.state('productList', {
views:{
"main_view":{
templateUrl: 'pages/productList.html',
controller: 'productListController'
},
"second_view":{}
}
});
$stateProvider.state('productDetail', {
views:{
"main_view":{
templateUrl: 'pages/productDetail.html',
url:'/productDetail',
params:{
productObj: null
},
controller: 'productDetailController',
},
"second_view":{}
}
});
}
MyApp.controller('productListController',function($state,$scope,$http, $window){
$http
.get('api/item/index')
.then(function (response) {
$scope.items = response.data;
});
$scope.showProductDetails = function(argItem){
console.log(argItem); // will show the argItem object in logs
$state.go('productDetail',{productObj:argItem}); // here is the problem
}
});
MyApp.controller('productDetailController',function($stateParams,$state,$scope){
console.log($stateParams); //Empty
console.log($state.params) //Empty
});
<!-- using AngularJs v1.5.5 and ui-router v0.2.18 -->
<!-- this is pages/productList.html templateUrl page-->
<article ng-repeat="item in items">
<div class="thumbnail">
<a ng-click="showProductDetails(item)" class="btn btn-info">{{item.name}}</a>
</div>
</article>
the params : {} does not belong to view, but to state:
$stateProvider.state('productDetail', {
// this, state level, is a right place for params
params:{
productObj: null
},
views:{
"main_view":{
templateUrl: 'pages/productDetail.html',
url:'/productDetail',
// this is wrong place
// params:{
// productObj: null
// },
controller: 'productDetailController',
},
"second_view":{}
}
});
Related
I have a scenario where when I click on a link i need to change the route and also add send some params to the other state.
The issue here is the params are empty when I console it in other state
<div ng-repeat="items in vm.Items">
<a ng-click="vm.goToDetails(items.id)">{{items.title}}</a>
</div>
Controller:
vm.goToDetails = function(Id) {
$state.go('Details', {
'fid': Id
});
}
route:
$stateProvider.state('Details', {
url: '/details/:fid',
resolve: {
selectedProduct: ['$state', '$stateParams',
function($state, $stateParams) {
console.log($stateParams.fid) //getting empty string here
console.log($state.params.fid)//getting undefined here
}
]
}
});
Any help would be appreciated.
You need to specify the parameters name in the route url:
/some-route/:fid
I didn't find any issue with the code, may be the issue is with the injection of resolved parameter.
I created a DEMO with your code. This may be helpful to you.
Here is config,
app.config(function($stateProvider,$urlRouterProvider){
$stateProvider.state('Details', {
url: '/details/:fid',
templateUrl: 'detail.html',
controller: 'DetailController',
resolve: {
selectedProduct: ['$state', '$stateParams',
function($state, $stateParams) {
console.log($stateParams.fid) //getting empty string here
alert($stateParams.fid) //getting empty string here
return $stateParams.fid
}
]
}
});
$stateProvider.state('login',{
url: '/login',
templateUrl: 'login.html',
controller: 'LoginController'
});
$urlRouterProvider.otherwise('/login');
});
Controller that contains repeated object,
app.controller('LoginController',function($scope,$state){
$scope.Items = [{id: 1,title: "Title1"},{id: 2,title: "Title2"},{id: 3,title: "Title3"}]
$scope.goToDetails = function(Id) {
console.log(Id)
$state.go('Details', {
'fid': Id
});
}
})
This is the controller where you can inject selectedProduct
app.controller('DetailController',function($scope,$state,selectedProduct){
$scope.selectedProduct = selectedProduct;
})
PLEASE CHECK THIS DEMO
I want to create a method which can load the controller and template of each page on demand, when route changes and make the state url option have 2 parameters with the second one optional so that one of the pages can load additional information inside another ui-view based on that parameter. Can anyone help me?
Javascript:
.config(function config($stateProvider) {
$stateProvider.state("index", {
url:"",
controller:"FirstCtrl as first",
templateUrl: "templates/first.html"
})
$stateProvider.state("second", {
url:"/second",
controller:"SecondCtrl as second",
templateUrl: "templates/second.html"
})
$stateProvider.state("third", {
url:"/third",
controller:"ThirdCtrl as third",
templateUrl: "templates/third.html"
})
})
Try this,
js
$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 ... }
}
}
})
Html
<body>
<div ui-view="filters"></div>
<div ui-view="tabledata"></div>
<div ui-view="graph"></div>
</body>
please refer this link https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
This is my code, I need ui-view="tabs" to work properly, but when i add it inside ui-view="details" an error occured
(angular.js:13550TypeError: Cannot read property 'name' of undefined)
$stateProvider
.state('home',{
views:{
'tabs' :{
templateUrl: 'http://v.eyp.iypcdn.com/static/mobile/js/app/html/home.html',
controller: 'HomeController'
}
}
})
.state('categories', {
views:{
'tabs' :{
templateUrl: 'http://v.eyp.iypcdn.com/static/mobile/js/app/html/categories.html',
controller: 'CategoriesController'
}
}
})
.state('categoryDetails',{
views:{
'details': {
templateUrl : 'http://v.eyp.iypcdn.com/static/mobile/js/app/html/categoryDetails.html',
controller: 'CategoryDetailsCtrl'
}
},
params:{
cat: 'all'
}
})
<div ui-view="details">
<div ng-controller="TabsController" class="tabsdemoDynamicTabs" layout="column">
<div ui-view="tabs" layout-fill class="demo-tab tab{{index%4}}">
<br>
</div>
</div>
</div>
your HTML suggests that tabs are nested view inside the details view. So, you'll need to define the state information accordingly.
try this:
.state('categoryDetails.home',{ & .state('categoryDetails.categories',{
Hope this solves it.. :)
Once my child state controller gets instantiated it does not reload again on $state.go
my router layout
.state('hotelsearch', {
url: '/search',
abstract: true,
views:{
'': {
templateUrl: "app/components/layout/layout.html"
},
"header#hotelsearch": {
templateUrl: "app/components/search/search.html"
},
"footer#hotelsearch": {
templateUrl: "app/components/footer/footer.html"
}
}
})
.state('hotelsearch.hotel', {
url: '',
views:{
'':{templateUrl: 'app/components/search/searchHotel.html'},
}
})
.state('hotelsearch.hotel.main', {
url: '',
views:{
"main#hotelsearch": {
templateUrl: 'app/components/hotel/hotelSearch.html',
controller:"hotelResult"
},
},
})
.state('hotelsearch.flight', {
url: '',
templateUrl: 'app/components/search/searchFlight.html',
})
layout
<div ui-view="header"></div>
<div ui-view="main"></div>
<div ui-view="footer"></div>
state called on successfully resolving promise
.then(function(response){
console.log(response.data.message);
if(response.data.message==="Success"){
$state.go('hotelsearch.hotel.main');
}
controller hotelResult
function hotelResult(dataservice,$scope,$stateParams){
console.log($stateParams);
dataservice.makeRequestForHotel()
.then(function(response){
console.log(response);
$scope.data=response.data.HotelGroup[0].City;
});
}
i know the controller is not reloading a second time because console.not working.
What i have tried:
1.using resolve.
2.reload:true in `$state.go`
(this causes the entire view controllers to be reloaded, as a result i get the data but the data in the suggestion box of search controller is lost)
what i am looking for is only selective reloading of the an individual state child controller
My problem is quite specific so I haven't been able to find an answer for this particular scenario anywhere, I did manage to get the functionality I require but would like to know if there is a better way of doing it. I will start by explaining the problem.
In index.html I have the following:
<html>
...
<lumx-navbar></lumx-navbar>
<div class="wrap">
<div ui-view></div>
</div>
...
</html>
lumxnavbar is a directive for the navigation bar of the application
nav.js
module.exports = function(appModule) {
appModule.directive('lumxNavbar', function(UserFactory, $window, $rootScope) {
return {
template: require('./nav.html'),
controller: function($scope) {
$scope.nav = require('../../static-data/nav.json');
$scope.user = $rootScope.user;
$scope.logout = function() {
UserFactory.logout();
$scope.user = '';
$window.location.href = '/#/login';
};
}
};
});
};
nav.html
<header>
...
<span ng-show="user" class="main-nav--version">Logged in as: {{user}}</span>
...
</header>
So the application starts with a login page at which point there is no user variable available anywhere. Once the user logs in there will be a user returned from a service.
my routes look like this (I am using angular-ui-router)
$stateProvider
.state('anon', {
abstact: true,
template: '<ui-view/>',
data: {
access: false
}
})
.state('anon.login', {
url: '/login',
template: require('../views/login.html'),
controller: 'LoginCtrl'
});
$stateProvider
.state('user', {
abstract: true,
template: '<ui-view/>',
data: {
access: true
}
})
.state('user.home', {
url: '/home',
template: require('../views/home.html'),
controller: 'HomeCtrl'
})
...
so the idea is that once the user logs in the navbar will change from
to this:
the only way I have found to accomplish this reliably is to do the following
instantiate a variable in $rootScope
appModule.run(function($rootScope, $location, UserFactory, $state) {
$rootScope.user = UserFactory.getUser();
...
then set the same variable from the login controller
...
$scope.login = function (username, password) {
UserFactory.login(username, password).then(function success(response) {
$rootScope.user = response.data.user.username;
$state.go('user.home');
}, handleError);
};
...
so this will update the navbar because of this line in the directive $scope.user = $rootScope.user; but my question is whether there is a better way of doing this without using $rootScope or would this be a suitable use for it?
Any input would be appreciated...:)