Passing multiple parameters in $stateParams - angularjs

In the ui-router tutorial https://plnkr.co/edit/jbZgIg?p=info, they are passing a single parameter personId to the state.
ui-sref="people.person({ personId: person.id })"
and the state is:
{
name: 'people.person',
url: '/{personId}',
component: 'person',
resolve: {
person: function(people, $stateParams) {
return people.find(function(person) {
return person.id === $stateParams.personId;
});
}
}
}
I am working on an example in which I want to pass 2 parameters (1 visible using the url, and the second hidden which will be the id that the user can't see in the url). Something similar to:
ui-sref="people.person({ personId: person.id, personUri : person.uri })"
and I want the state to become something like this (but it didn't work!):
{
name: 'people.person',
url: '/{personUri}',
component: 'person',
resolve: {
person: function(people, $stateParams) {
return people.find(function(person) {
return person.id === $stateParams.personId;
});
}
}
}
As the state shows, I want to use the personUri in the url, and I want the personId to be passed to the people service.

You can use params
.state('other', {
url: '/:personUri',
params: {
personUri:"",
// this param is not part of url
// it could be passed with $state.go or ui-sref
personId: "",
}
...

Instead of passing your object in url parameters you can simply call your controller's function by passing in your object and then do whatever you want to do with that object in your controller itself and then call your service inside it.
Example:
$scope.func = function info(person){
console.log(person);
PeopleService.xyz(person).then(function(response){
console.log('Service called')
})
}
In html call it like this :
<button ng-click="func(person)"> Click me</button>

Related

ui-router's state params in data object

I am using ui-router's state data to decide what page title to display on the page. I have a specific scenario where one state might have 2 different page titles because it is shared.
Say I have page titles 'Directors' and 'HR'. These are parameters passed into the state by $state.go('main.employees', { pageType: 'HR' });
How can I possibly get data to return params.pageType like data: { pageTitle: this.params.pageType }. Is there a way to get params in data?
.state('main.employees', {
url: '/employees',
params: {
pageType: null
},
views: {
'content': {
templateUrl: 'app/employees/employees.html',
controller: 'employeesCtrl as vm'
}
},
data: {
pageTitle: this.params.pageType //<-- I have problem here
}
})
I have to use params.pageType only in this specific case because other states do not have this param. I am relying on $state.$current.data.pageTitle to display it.
I've also tried this but then when calling this with $state.$current.data.pageTitle() I get undefined...
data: {
pageTitle: function($state) {
return $state;
}
}
No need to use the data property. You can directly use the params in the controller using $stateParams service.
Ex-
$state.go('main.employees', { pageType: 'HR' });
$state.go('main.employees', { pageType: 'Directors' });
And in controller access the params as given below-
console.log($stateParams.pageType)

AngularJS : How to pas multiple parameters in route

I am building an application using AngularJs.
I suddenly stuck in a routing where I want to send multiple data in route but its not woking.
Her is my route :
.state('/filter-list', {
url: "/search/india/:data?",
views : {
"" : {
templateUrl:"/filter/filter-list.html",
controller: 'filterListCtrl',
controllerAs:'vm',
authenticated: true
}
},
resolve: {
loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load('/filter-list'); // Resolve promise and load before view
}]
}
})
I want to send data like this:
/search/india/state/city/hotel-name
But if I try to send this, it is redirected my application to home page.
only '/search/india/new-delhi' is working.
Can someone help me to solve this problem.
Thanks in advance.
you can add the params in your route like this:
.state('/filter-list', {
url: "/search/india",
params: {
state: '',
city: '',
hotel-name: ''
}
...
}
and in your controller you can use $state.go() method like this:
$state.go("/filter-list", {
state: 'your-chosen-state',
city: 'your-chosen-city',
hotel-name: 'your-chosen-hotel'
});
and inside your controller you can capture the params from:
const state = $stateParams.state;
const city = $stateParams.city;
const hotel = $stateParams.hotel-name;

ui-router: passing in a param that not in the url?

I am having a problem passing in a param that's not a parameter in the url.
I basically have the following on a click event
let stateParams = {
id: event.info.id,
info: event.info
};
this.$state.go('home.showinfo', stateParams);
I have double checked on the stateParams contains the id and also the info object.
I then have the following setup on the state
.state('home.showinfo', {
url: 'info/info/:id',
resolve: {
info: function($stateParams){
return $stateParams.info;
}
},
params: {
info: null
}
In my controller I am checking the value of $stateparams, and I see the id (also the URL contains the ID), but the info object is null. It's always null. I just want to be able to access it in the controller. Also "this.info" is also null.
I put a breakpoint in the resole and info is null.
I have tried removing the params:{} above and still nothing.
Any ideas what I am doing wrong?
There is a working plunker
The code should be working, check twice the calling side. These links will do what is expected:
<a ui-sref="home.showinfo({id:1, info:'hi'})">
<a ui-sref="home.showinfo({id:2, info:'bye'})">
There is a state as is above:
.state('home.showinfo', {
url: 'info/info/:id',
templateUrl: 'showinfo.tpl.html',
resolve: {
info: function($stateParams){
return $stateParams.info;
}
},
params: {
info: null
}
})
Check it here

Angular JS - Update Scope value on click

Right now I am passing my parameter through the state like:
.state('app.listing', {
url: '/ad/listing/:adId/{type}',
params: {
adId: {
value: "adId",
squash: false
}, type: {
value: null,
squash: true
}
},
This works as I can get "type" from $stateParams and update my get request.
Is there not a way to do this from a click event and not use $stateParams for passing the "type" param?
I basically have a button that filters results and passes the type param from the button. It would be a lot easier if I can just attach a click event to it which then updates my get request.
Just messing around I tried doing something like
$scope.filter = function(type) {
if(type) {
return type;
}
return '' ;
}
$scope.type = $scope.filter();
Service is like
$http.get(API_ENDPOINT.url + '/listing/' + adId, {
params: {
page: page,
type: type // essentially $scope.type
},
}).
and then on my button I have
<button ng-click="filter('2')"></button>
^ This will pass 2 for type, but won't reinit the http get call on click. Do I need to broadcast the change is there a simple way to do this?
Does this even make sense? The code above is just mock to give an idea, but open to suggestions if any.
Angular never requires you to make broadcasts to reflect changes made to scopevariables via the controller
var typeWatcher = '1';
$scope.filter = function(type){
if (type !== typeWatch)
{
$http.get(API_ENDPOINT.url + '/listing/' + adId, {
params: {
page: page,
type: type // essentially $scope.type
},
});
typeWatcher = type;
}
};
You can wrap your get call in a function & call it after the filter function in ng-click
$scope.functionName = function () {
return $http.get(API_ENDPOINT.url + '/listing/' + adId, {
params: {
page: page,
type: type // essentially $scope.type
}
})
}
then in HTML
<button ng-click="filter('2'); functionName()"></button>
Well, To call $http.get method on click,
$scope.filter = function(type) {
if(type) {
//call the method using service.methodName
return type;
}
return '' ;
}
and wrap that $http.get method to one function.
Hope it helps you.
Cheers

Angular ui router view loaded but not passing parameters

I'm working on a website with angular ui-router. There is a page which needs to pass some parameters to another view. I defined my states like this:
.state('locaties', {
url: "/locaties",
data: {rule: function($cookieStore) {} },
controller: "FranchisesCtrl",
templateUrl: "view/locaties.html"
})
.state('locaties.detail', {
params: {
locatieID: 1,
locatieName: "Derptown",
locatieLat: 50,
locatieLong: 50
},
url: "/:locatieName",
controller: "LocatieDetailCtrl",
templateUrl: "view/locatie.html",
resolve: {
locatiedetail:
function ($stateParams, $http){
var url ="http://website/api/franchises/" + $stateParams.locatieID + "/nl.json";
return $http.get(url).then(function(res){
return res.data;
});
}
}
})
Inside LocatieDetailCtrl there's this
angular.module('PremiumMeat').controller('FranchisesDetailCtrl',
function ($scope, $window, franchisedetail) {
$scope.franchiseDetail = franchisedetail;
});
The "Locaties" (plural) view works properly and when I click on a specific "locatie" (single), the url changes and the view gets loaded within the locaties view and no parameters are passed. On the image you can see the top 2 items from the "locaties" view. Then a single locatie is loaded under the "locaties" view. This should be a new page (view) with the parameters from the clicked locatie. Can anyone help me / explain, I'm rather new to angular, thank you.
Solution
The parameters where hard-coded, to make them dynamic, syntax needed adjustment according to angular docs.
params: {
locatieID: {value : "1"},
locatieName: {value : "Stad"},
locatieDescr: {value : "Beschrijving"},
locatieLat: {value: 51.2},
locatieLong: {value : 4.4}
},
Where parameters are passed with ui-href like this
<a ui-sref="locaties.detail({
locatieID: item.id,
locatieName: item.name,
locatieDescr: item.description,
locatieLat: item.location[0].lat,
locatieLong: item.location[0].long
})"
class="detail">Bekijk detail >></a>
The 'params' defined should return the key-value pair object.
But it is a better practice if you are passing values from one state to another to use 'data' instead of appending everything in the URL.
The following code should work :
//The following values are default values of the parameters
.state('locaties.detail', {
params: {
locatieID: '1',
locatieName: 'Derptown',
locatieLat: '50',
locatieLong: '50'
}, ........
This should work. The values expected are of string type and not number.
As far as your LocatieDetailCtrl is concerned, you need to inject what you have in the resolve of the 'locaties.detail' state (i.e. 'locatiedetail'). So your 'LocatieDetailCtrl' should look like following:
angular.module('PremiumMeat').controller('FranchisesDetailCtrl',
function ($scope, $window, franchisedetail, locatiedetail) {
$scope.franchiseDetail = franchisedetail; //make sure you have franchiseDetail as well.
$scope.locatiedetail = locatiedetail;
});
I hope that will work.

Resources