$state.go() is not passing params to url - javascript

I was using ui-sref for this. It worked fine but I can't use it in this situation because I'm using a ng-repeat and I don't want it to be executed on every item. So I decided to make a function, which contains a simply $state.go() with a param.
defining:
.config(
["$stateProvider", // more dependencies
($stateProvider: angular.ui.IStateProvider) => {
$stateProvider
.state("app.projectstart.project", {
url: "project/:parentId",
templateUrl: "gui/projectstart/project/project.html",
controller: "ProjectstartProjectController"
});
}
]);
calling:
this.modelFactory.$state.go("app.projectstart.project", {parentId: item.parentId});
I want the url to be like
"http://localhost:9000/#/app/projectstart/project/10000?functionId=clockin"
But the only thing I get is
"http://localhost:9000/#/app/projectstart/project/?functionId=clockin"
Why is it not passing the parentId to the url? I defined it in .config.
Thanks in advance.
greetings johnny
Edit:
I'm sure that 'item.parentId' has a Value. It's either '10000' or '20000'. I assigned parentId with '10000', It's still the same.

Related

Angular ui-router: load values for data and params from service

I want to load data and params for each state once when the app loads from my service settings (this service returns also promise since data are loaded asynchronously).
Something like this:
.state('tutorials', {
url: '/tutorials',
templateUrl: 'partials/tutorials.html',
controller: 'TutorialsCtrl',
data: {details: false}, // instead of false I want: settings.get('tutorials_data_details')
params: {popular: '512'} // instead of '512' I want: settings.get('tutorials_params_popular')
})
Those params must be loaded for all states before entering any state since they are used to build links with ui-sref directive that can be placed in any html pointing to any state (and those default params will be used).
Problem is that I cannot inject service into the config function. And using resolve will not handle all states at once.
I think $stateProvider.decorator could be used but I don't know how.
I would have commented, but not enough reputation for that.
If it's possible, one option is to create a parent abstract state such as app, so your state tree would become app.tutorials and then you can use resolve on the app state, allowing all sub-states to use the data/params.
something like this:
.state('app', {
url: '',
abstract: true,
templateUrl: 'partials/tutorials.html',
controller: 'AppCtrl',
resolve: { <resolve your dependencies here> }
})
.state('app.tutorials', {
url: '/tutorials',
templateUrl: 'partials/tutorials.html',
controller: 'TutorialsCtrl'
})
Note the Tutorials state wont load until the resolve is completed.
After some research and thinking I came up with these 3 possible solutions:
1) By using decorator we make all states resolving settings service.
.decorator('data', function(state, parent) {
state.resolve.SettingsLoaded = ['settings', function(settings) { return settings.$promise; }];
return parent(state);
})
Then in settings service use load success callback to setup states. You can use $state.get() to get all states (or with string parameter to get specific state by name) and modify the params object.
NOTE that you cannot use short version like state.params.popular = '512' but the full one: state.params.popular.value = '512'.
2) Those params could be actually functions that will be injected and invoked, and the result value will be used.
So the new params definition in the state will be:
params: {popular: ['settings', function(settings) { return settings.get('tutorials_params_popular') || '512'; }]}
Also I used again the same decorator to make sure settings will be resolved before any state is loaded.
I like this approach the most since all parameter values stays in settings service and the change is being dynamically reflected.
3) Since I'm using RequireJS, I could load settings using that and then inject it to the router file. This would however require more changes to the exising code in my settings service...

Get $stateParams without ui-nav

Can you somehow receive $stateParams without having a <ui-view>-tag in your html?
Basically, I want this code to work:
.config([
'$locationProvider',
'$stateProvider',
function($locationProvider, $stateProvider) {
$locationProvider.html5Mode(true);
$stateProvider
.state('schedules_show', {
name: 'edit_schedule',
url: '/schedules/:id/edit'
});
}])
So I can fetch the :id from any other controller that is being called via $stateParams.
Some more clarification: I don't want to use $stateParams to generate links or to move around my application, cause my app is an hybrid of RoR and Angular.js. I change views in server side with common links. I just want to use angular-ui-router to get some values from the URL to use in the Angular.js part of my app (in this case the :id). So because I don't want to navigate via Angular and don't want to use it's state dependent controllers or views, which again is the reason why I don't want to have <ui-view>-tags in my HTML.
Problem solved: I think my approach via angular-ui-router was wrong. I have a solution now, where I just pass the param from the HTML via ng-init to the controller, but it doesn't answer my question, so I think this should be closed.
If I understood you rigth you need state params. And the qnswer is: yes you can. First way is to use url params: /url/suburl/:param1/:param2/:paramN. Second way (if you do not want to see your params in url) use params option in your state. Then just call your state with this params inside. Example:
.state('schedules_show', {
name: 'state1',
url: '/state',
params: {
param1: null,
param2: null
}
});
Here, in state configuration null is for not to assign initial value; and call this state with
ui-sref="state1({ param1: 'test', param2: 10 })"
Then in injected $stateParams object you can get these params' values
Another possible solution is to use resolve in your state to provide specific params to your controller assigned with this state
More info about resolve
Does it makes sense?

How to structure a multi step wizard with ajax calls in angularjs

I want to build a multi step wizard with ajax calls in between:
I currently use ui.router for views of the wizard steps which works fine.
On the first page the users enters some data e.g. playerid.
On the second page i want to display some data pulled from the server corresponding to that playerid.
How should i structure that? Because i read that controllers should only write to the model, but i need to read playerid the user entered to make the ajax call..?
Here is a Plunk how i do it right now:
http://plnkr.co/edit/4ZEdYHUqovn2YfkUpp2y?p=info
I personally would have done it this way (plunker):
The routing :
$stateProvider
.state('view1', {
url: "/view1",
templateUrl: "view1.html",
controller:"WizardCtrlStep1"
})
.state('view2', {
url: "/view2",
templateUrl: "view2.html",
controller:"WizardCtrlStep2",
params:{
playerId:null
},
resolve:{
player:function($http, $stateParams){
//you can use the player id here
console.log($stateParams.playerId);
return $http.get("test.json");
}
}
})
I really really like to have a single controller per state. It avoid thing to get messy.
I also use a resolve to do the ajax call before the step2 view loading.
Here is the controller of the 2nd step
//I inject the "player" resolved value
controller('WizardCtrlStep2', function($scope, player) {
$scope.name = 'World';
//to access the result of the $http call use .data
$scope.player = player.data;
})
And finally the HTML
<input type="text" ng-model="main.playerId">
<button ui-sref="view2({playerId:main.playerId})">proceed</button>
Here i give ui-sref a param for "playerId" that will be used in the resolve function.
Hope it was clear, if you have any question feel free to ask.

Angularjs - Get URL parameters from inside the when() function

Given the following code:
$routeProvider.when('/movies/:type', {
title: 'Movies',
templateUrl: 'pages/movies/movies.html',
controller: 'MoviesCtrl'
});
How can I access the :type param from inside the when function? I want to do something like so:
$routeProvider.when('/movies/:type', {
title: 'Movies' + ' - ' + :type,
templateUrl: 'pages/movies/movies.html',
controller: 'MoviesCtrl'
});
That value in title must be dinamically generated.
Thanks in adv.
I'm not sure why you are extending the route (config) object, but you are able to access routeParams from within your controller. That is also the recommended way.
The $routeParams service allows you to retrieve the current set of route parameters.
angular.module('MyModule').controller('MoviesCtrl',function($scope, $routeParams) {
$scope.currentMovieType = 'Filmes-' + $routeParams.type;
});
Let's say your route is something like that /movies/scifi. In this case $scope.currentMovieType becomes scifi and you can use {{currentMovieType}} in your view to populate this value. You can find detailed informations in the documentation.
Note that the $routeParams are only updated after a route change completes successfully. This means that you cannot rely on $routeParams being correct in route resolve functions. Instead you can use $route.current.params to access the new route's parameters.
It is not really possible, because the route config object is not as dynamic as you think. Whatever you put in the route configuration object, it cannot depend on the value that the route param is going to take in the future. Think of how this code gets executed : the configuration object will be evaluated only once, when the route is configured.
On the other hand, if you want to change the page's title when going through this route, you can do it using the $routeParamsservice to access the param value, and the $document service to change the page's title, either in a controller or in a resolveclause.
An example with the latter option:
$routeProvider.when('/movies/:type', angular.extend({
templateUrl: 'pages/movies/movies.html',
controller: 'MoviesCtrl',
resolve: {
title: ['$routeParams','$document', function ($routeParams, $document) {
var title = 'Filmes-' + $routeParams.type;
$document.title = title;
return title;
}]
}
}, routeParams));
That works also in a controller of course.
Some notes on your code :
I'm not even sure that there is a point setting a title property in a route config object, I don't see it in the documentation at least.
That second argument routeParams in that angular.extend call - the name is confusing, one could mistake it for the $routeParams service. I think you should call it routeDefaults or something like that instead.
Give a try to $location.absUrl(); requires some calculation too .
https://docs.angularjs.org/api/ng/service/$location

Angular $routeParams force variable type

In my Angular app, I have routes like /items/:id
$routeProvider
.when('/items/:id', {
templateUrl: 'views/items.html',
controller: 'ItemCtrl'
})
In ItemCtrl I get :id with $routeParams.parcId The problem is it's a string while the value is a number and all my id are numbers.
So how to force the correct type and not having string by default?
ps: I don't want to do var id = Number($routeParams.parcId) in all my controllers
I did it using the $routeChangeStart event.
In your app.js file, add the following line to the .run function as :-
angular.module('test1App').run(function ($rootScope) {
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (next.params.hasOwnProperty('id')) {
next.params.id = Number(next.params.id);
}
});
});
Description: On every change of route, it checks if there is a parameter named 'id'. If yes then it changes it to a number.
Hope it helped.
You need to use resolve in routes and update the variable. Then use this resolved variable in controller
Example
did you try like this?
parseInt($routeParams.parcId)

Categories

Resources