I have to open the new tab using state.go with parameter,
State config:
.state("view", {
url: "/view",
templateUrl: 'app/components/view/view.html',
controller: 'viewController',
params: {
data: ''
}
})
In the some controller:
var url = $state.href('view', {data: JSON.stringify($scope.data)});
window.open(url,'_blank');
When i tried above code its redirecting to new tab but i can't able to get the passed params values in the viewcontroller.
In your controller you have to inject $stateParams like
.state("view", {
url: "/view/:data",
templateUrl: 'app/components/view/view.html',
controller: 'viewController'
})
.controller('viewController', ['$stateParams', function($stateParams) {
$scope.params = $stateParams.data; // here you get parameter values
})
Related
// Angular factory
wpApp.factory('Posts', function ($resource) {
return $resource(appInfo.api_url + 'posts/:ID', {
ID: "#id"
})
});
// Index page controller.
wpApp.controller('ListCtrl', ['$scope', 'Posts', function ($scope, Posts) {
$scope.page_title = "Blog Listing";
Posts.query(function(res) {
$scope.posts = res;
})
}]);
// Show page controller.
wpApp.controller('DetailCtrl', ['$scope', '$stateParams', 'Posts', function($scope, $stateParams, Posts) {
console.log($stateParams);
Posts.get({ ID : $stateParams.id }, function(res) {
$scope.post = res;
});
}]);
// Angular app configuration.
wpApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state( 'list', {
url: '/',
controller: 'ListCtrl',
templateUrl: appInfo.template_directory + 'templates/list.html'
})
.state('detail', {
url: '/posts/:id',
controller: 'DetailCtrl',
templateUrl: appInfo.template_directory + 'templates/detail.html'
})
});
From code in DetailsCtrl, I understood that we are going to do a GET request by calling url with id == id passed to angular url params.
But what does this ID: "#id" do? What is it used for? How does it work?
Per the docs.
If the parameter value is prefixed with #, then the value for that parameter will be extracted from the corresponding property on the data object (provided when calling actions with a request body). For example, if the defaultParam object is {someParam: '#someProp'} then the value of someParam will be data.someProp. Note that the parameter will be ignored, when calling a "GET" action method (i.e. an action method that does not accept a request body)
So in your case that second argument is simply configuring defaults for your URI. In this case it is making the URI value of ID dynamic.
I am passing a value from one state to another using UI-Router. In my controller when the url is updated I am trying to get access to the second parameter of my url using $stateParams, but for some reason I can get access to the first parameter but the second one is UNDEFINED. This is my code:
state 1, URL:
http://localhost:16009/#/5nqeAPqlv21/
state 2, URL:
http://localhost:16009/#/5nqeAPqlv21/details/PP163Ku3dOR
candidateContoller.js:
//go to state 2 (same controller for parent and child views)
$state.go('index.details', { "submissionIdd": publicSubmissionId });
//when located in the new state and new url:
console.log($stateParams.submissionIdd); //shows undefined
console.log($stateParams.token); //shows 5nqeAPqlv21
App.js:
$stateProvider
.state('index',
{
url: '/:token/',
views: {
'': {
templateUrl: 'AngularJS/Templates/indexView.html',
controller: 'candidateController as candCtrl'
},
'sectioncandidate#index': {
templateUrl: (_isNotMobile)
? 'AngularJS/Templates/candidatesView.html'
: 'AngularJS/Templates/candidatesMobileView.html'
}
}
})
.state('index.details', {
url: 'details/{submissionIdd}',
views: {
'sectioncandidate#index': {
templateUrl: (_isNotMobile)
? 'AngularJS/Templates/candidateView.html'
: 'AngularJS/Templates/candidateMobileView.html'
}
}
})
You do experience standard behavior of the UI-Router and Parent/Child state defintion:
parent state declares $stateParams (as url: '/:token/') - so there is just one declared - a token
child state gets all from parent(s), plus declares new parameter (as url: 'details/{submissionIdd}') - so it has both defined - token and submissionIdd,
So, while child has access to both params, parent state has just a token parameter
state 1 === PARENT, URL:
http://localhost:16009/#/5nqeAPqlv21/
here we will have submissionIdd undefined
state 2 === CHILD, URL:
http://localhost:16009/#/5nqeAPqlv21/details/PP163Ku3dOR
both are there submissionIdd=PP163Ku3dOR and token=5nqeAPqlv21
Extend - there is a working plunker
This states definition (in the plunker a bit adjusted)
.state('index',
{
url: '/:token/',
views: {
'': {
templateUrl: 'indexView.html',
controller: 'candidateController as candCtrl'
},
'sectioncandidate#index': {
templateUrl: 'parent.html'
}
}
})
.state('index.details', {
url: 'details/{submissionIdd}',
views: {
'sectioncandidate#index': {
templateUrl:'child.html',
}
})
will properly show state params for these links
href
<a href="#/5nqeAPqlv21/">
<a href="#/5nqeAPqlv21/details/PP163Ku3dOR">
<a href="#/5nqeAPqlv21/details/other">
ui-sref
<a ui-sref="index({token: '5nqeAPqlv21'})">
<a ui-sref="index.details({token: '5nqeAPqlv21', submissionIdd: 'another'})">
Check it here
You can prefer not to pass the the params in the URL unless there is an explicit requirement. I would prefer to use $stateParams in controller to fetch the data.
For this you need to define the default params in the state to
make it work.
$stateProvider .state('index.details', {
url: 'details',
params: {
submissionIdd: 'default',
},
views: {
'sectioncandidate#index': {
templateUrl: (_isNotMobile) ? 'AngularJS/Templates/candidateView.html' : 'AngularJS/Templates/candidateMobileView.html' ,
controller: function($stateParams){
console.log($stateParams.submissionIdd)
}
}
}
})
This should be simple but I just can't figure it out.
I have two routes:
$stateProvider
.state('users', {
url: '/users',
views: {'#': {
templateUrl: 'templates/users.tpl.html',
controller: 'UsersCtrl as users'
}}
})
.state('users.edit', {
url: '/{userId}',
views: {'#': {
templateUrl: 'templates/editUser.tpl.html',
controller: 'EditUserCtrl as editUser'
}}
});
This works fine if you use a ui-sref or $state.go to navigate to the "users" state by name, but if you type domain.com/users/ into the URL bar it goes to the edit state with empty userId parameter even though there is nothing after the trailing stash.
Normally this wouldn't be a problem but firing the editUser route with no userId causes console errors which would be a pain to fix.
Is this easily fixable?
Take a look to this post:
https://github.com/angular-ui/ui-router/issues/50
and this link referenced in the post:
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-make-a-trailing-slash-optional-for-all-routes
Your states definition should be
$stateProvider
.state('users', {
url: '/users',
views: {'#': {
templateUrl: 'templates/users.tpl.html',
controller: 'UsersCtrl as users'
}}
})
.state('users.edit', {
url: '/edit/{userId}',
views: {'#': {
templateUrl: 'templates/editUser.tpl.html',
controller: 'EditUserCtrl as editUser'
}}
});
your child state url should be '/edit/{userId}'. When we create a child state its url automatically added its parent state url. So if your url is '/{userId}' it will be 'domain.com/users/{userId}'. That's why for domain.com/users/ its navigate to the state users.edit with null parameter value.
https://github.com/angular-ui/ui-router/wiki/nested-states-%26-nested-views
I am using UI-Router to navigate to detailed view. It changes state correctly and passes parameters correctly, yet the url address in the browser stays unchanged. I would like to display the passed params in the url.
app.js
'use strict';
var myApp = angular.module("myApp", ['ui.router']);
myApp.config(['$stateProvider', '$urlRouterProvider','$locationProvider',
function($stateProvider, $urlRouterProvider,$locationProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('/', {
url: '/',
templateUrl: 'partials/listView.html'
})
.state('list', {
url: '/',
templateUrl: 'partials/listView.html'
})
.state('detail', {
url: '/detail/:key',
params: {
key: { value: "" }
},
templateUrl: 'partials/detailView.html',
controller: 'DetailController'
})
// use the HTML5 History API
$locationProvider.html5Mode(true);
}]);
Controller function to go to the detail state:
myApp.controller('MainContr', [ '$scope', '$http', '$location', '$state',
'$filter','$rootScope', MainContr ]);
function MainContr($scope, $http, $location, $state, $filter,$rootScope) {
$scope.goDetailView= function(key){
console.log("trying to change url ");
// changes state correctly, and passes params to DetailController,
// but does not change browser address url.
// How can I update the url in browser here?
$state.go('detail',
{key: $scope.selectedPDFKey},
{
location:true
});
}
}
// detail view
myApp.controller('DetailController', [ '$scope', '$stateParams'
DetailController ]);
function PDFDetailController($scope,$state)
{
$scope.currentKey=$state.params.key;
}
If I remove params in $state.go('detail'), the url in browser address bar is replaced. How can I get url in browser address bar replaced as well when I pass parameters in $state.go(). Thank you.
Issue was fixed when state was changed to use query in url as:
.state('detail', {
url: '/detail?key',
params: {
key: { value: "" }
},
templateUrl: 'partials/detailView.html',
controller: 'DetailController'
})
I came across this, but in my case it was just a missing / at the beginning of the url. So this is wrong:
.state('detail', {
url: 'detail/:key',
templateUrl: 'tpl.html'
});
And this is correct/working:
.state('detail', {
url: '/detail/:key',
templateUrl: 'tpl.html'
});
I dont needed any <base> tags in my <head> at all. My application is in a subfolder called /app.
By default - UI-Router will always show the param in address bar, if is defined in the url (not just in params : {} option)
To prove it, there is a plunker with your scenario, which does what you would expect - http://plnkr.co/edit/9uBlhNoNqZsjAJEdIhYa?p=preview
Links
<a ui-sref="list">
<a ui-sref="detail({key:1})">
<a ui-sref="detail({key:22})">
A state def (as yours)
.state('list', {
url: '/',
templateUrl: 'tpl.html',
controller: 'ParentCtrl',
})
.state('detail', {
url: '/detail/:key',
params: {
key: { value: "" }
},
templateUrl: 'tpl.html',
controller: 'ChildCtrl',
});
Check it here
(you can run it in separate window, by clicking the icon in the top right corner - and see the address bar with a key param)
What I am trying to do is within the Search controller, once I get the search results back from the server ($http) change view to a different view - the search results view. I am not sure if the approach I am going about it is right, but either-way it doesn't seem to be working. I will need to pass the response as well, so the new view can display the results/response.
My app.js:
.....state('tab.search', {
url: '/search',
views: {
'tab-search': {
templateUrl: 'templates/tab-search.html',
controller: 'SearchCtrl as search'
}
}
})
.state('tab.search-results', {
url: '/results',
views: {
'tab-search-results': {
templateUrl: 'templates/tab-search-results.html',
controller: 'SearchResultsCtrl as searchResults'
}
}
})
Then my search controller has:
.controller('SearchCtrl', function($scope, $state, $location, $ionicPopup, service) {
....
$scope.doSearch = function(state) {
.....
var result = service.doSearch(dataObj);
result.then(function(response) {
console.log("I'm here");
$state.go('tab.search-results');
......
My search results view (tab-search-results.html) has the following basic code at the moment:
<ion-view view-title="Search Results">
<ion-content padding="true">
hello world
</ion-content>
</ion-view>
This basic structure is how all my other pages/views are setup too.
What happens when I perform the search is that the console message gets outputted, and then the URL changes to /results as per the tab.search-results state, but the template/view doesn't change/show.
Interestingly if I change $state.go('tab.search-results'); to point to another app state/view that I know works, it works perfectly - but for whatever reason this state/view isn't working.
Also, if there is a better way of achieving this same thing, then please let me know. I will be needing to eventually pass the "response" from SearchCtrl to SearchResultsCtrl - or rather access it on the search results page in one form or another.
Many thanks.
I think you are looking for $stateParams.
var result = service.doSearch(dataObj);
result.then(function(response) {
$state.go('tab.search-results', {'searchData':response});
}
In your routes file:
.state('tab.search-results', {
url: '/results/:searchData',
views: {
'tab-search-results': {
templateUrl: 'templates/tab-search-results.html',
controller: 'SearchResultsCtrl as searchResults'
}
}
})
And in your SearchResultsCtrl:
.controller($stateParams) {
console.log($stateParams.searchData) // will give you search results
}
NOTE:If you don't want to pass data through the URL you can use params key in the .state() method.
.state('tab.search-results', {
url: '/results',
params: {
'searchData':null
},
views: {
'tab-search-results': {
templateUrl: 'templates/tab-search-results.html',
controller: 'SearchResultsCtrl as searchResults'
}
}
})
I realised why my view wasn't changing properly. The fix was changing the views in the sub-view to reference the parent view.
Fail (sub-view has unique name from parent):
.....state('tab.search', {
url: '/search',
views: {
'tab-search': {
templateUrl: 'templates/tab-search.html',
controller: 'SearchCtrl as search'
}
}
})
.state('tab.search-results', {
url: '/results',
views: {
'tab-search-results': {
templateUrl: 'templates/tab-search-results.html',
controller: 'SearchResultsCtrl as searchResults'
}
}
})
Success (sub-view references parent, 'tab-search'):
.....state('tab.search', {
url: '/search',
views: {
'tab-search': {
templateUrl: 'templates/tab-search.html',
controller: 'SearchCtrl as search'
}
}
})
.state('tab.search-results', {
url: '/results',
views: {
'tab-search': {
templateUrl: 'templates/tab-search-results.html',
controller: 'SearchResultsCtrl as searchResults'
}
}
})
Thanks all, I think I worked out the problem. It was putting the search results page under the tab abstract state. eg: tab.search-results rather than search-results - I am guessing this was the problem as there is no search results tab. When I re-named the state to just search-results (and modified the $state.go to use 'search-results' instead of 'tab.search-results') it worked. Does this seem right?