I have the following routing:
$stateProvider
.state('message', {
parent: 'admin',
url: '/message',
templateUrl: './app/gol88/admin/messaging/page/list.page.html',
controller: 'ListController as listCtrl'
})
.state('replyMessage', {
parent: 'message',
url: '/{ticketId:int}/reply', //this should have {id} as stateParams
onEnter: ['$mdDialog', '$state', function($mdDialog, $state) {
$mdDialog.show({
controller: ReplyController,
controllerAs: 'replyCtrl',
templateUrl: '/app/gol88/admin/messaging/page/dialog/reply.html',
parent: angular.element(document.body),
clickOutsideToClose:true
}).then(function(response) {
}, function() {
$state.go('message');
});
}],
onExit: ['$mdDialog', function($mdDialog) {
$mdDialog.hide();
}]
})
;
When I tried to navigate to replyMessage state for the first time and use the $stateParams.ticketId in my Controller I am getting the value. However, when I transitioned to message state , and try to transition to replyMessage state back again, the $stateParams.ticketId is now undefined. Why is that so?
This is my controller for replyMessage state:
var ReplyForm = require('../model/reply_form.model');
ReplyController.$inject = ['$stateParams', 'TicketApiService'];
function ReplyController($stateParams, TicketApiService) {
var vm = this;
vm.ticket = null;
vm.ReplyForm = ReplyForm;
vm.addComment = addComment;
init();
function init() {
console.log($stateParams.ticketId);
/* TicketApiService.details($stateParams.ticketId)
.then(function(response) {
vm.ticket = response;
})
;*/
}
function addComment() {
TicketApiService.addComment($stateParams.ticketId, vm.ReplyForm.toPayload())
.then(function(response) {s.
vm.ticket.comments.unshift(response);
vm.ReplyForm.reset();
})
;
}
}
module.exports = ReplyController;
Related
I am trying to pass an object by a simple $state.go(), but all I get is default values 0 and ""
angular ui router:
placesApp.config(($stateProvider, $urlRouterProvider) => {
$urlRouterProvider.otherwise("/home");
$stateProvider
.state("home", {
url: "/home",
templateUrl: "views/search-result.html",
controller: "HomeCtrl"
})
.state("placeDetail", {
url: "/place-detail",
templateUrl: "views/place-detail.html",
controller: "PlaceDetailCtrl",
params: {
placeId: 0,
placeImg: ""
}
})
});
The link that triggers the function:
<a ui-sref="placeDetail" class="place-name" ng-bind="place.venue.name" ng-click="goToPlaceDetail()"></a>
Place detail function, I should not that this is not HomeCtrl. It is in a directive related to HomeCtrl:
placesApp.directive("placeGrid", () => {
return {
restrict: "E",
replace: true,
controller: ["$scope", "$state", "$stateParams", ($scope, $state, $stateParams) => {
var imgObj = $scope.place.venue.photos.groups[0].items[0];
var placeId = $scope.place.venue.id;
var placeImg = imgObj.prefix + "1280x600" + imgObj.suffix;
var placeInfo = {placeId: placeId, placeImg: placeImg};
$scope.goToPlaceDetail = () => {
$state.go("placeDetail", {placeInfo: placeInfo});
};
}],
templateUrl: "views/place-grid.html"
}
});
placeDetail controller:
placesApp.controller("PlaceDetailCtrl", ["$scope", "$state", "$stateParams", ($scope, $state, $stateParams) => {
$scope.placeId = $stateParams.placeInfo.placeId;
$scope.placeImg = $stateParams.placeInfo.placeImg;
}]);
Don't create new placeInfo property. just pass the object.
var placeInfo = {placeId: placeId, placeImg: placeImg};
$scope.goToPlaceDetail = () => {
$state.go("placeDetail", placeInfo);
};
And access the property like this
$scope.placeId = $stateParams.placeId;
OR
add a new property to state
.state("placeDetail", {
url: "/place-detail",
templateUrl: "views/place-detail.html",
controller: "PlaceDetailCtrl",
params: {
placeInfo: {
placeId: 0,
placeImg: ""
}
}
})
Sorry Have you tried something like:
In your app.config:
.state("placeDetail", {
url: "/place-detail/:placeId/:placeImg",
templateUrl: "views/place-detail.html",
controller: "PlaceDetailCtrl",
params: {
placeId: 0,
placeImg: ""
}
})
then in your HTML:
<a ui-sref="placeDetail({id:place.venue.id,placeImg:place.venue.name})" class="place-name" ></a>
then in your controller (or where you need to get them from url):
placesApp.controller("PlaceDetailCtrl", ["$scope", "$state", "$stateParams", ($scope, $state, $stateParams) => {
function init(){
$scope.placeId = $stateParams.placeId;
$scope.placeImg = $stateParams.placeImg;
}
init();
}]);
In my main module i have used ui-bootstrap modal for checking login authentication.From run block i have called to loginModal service but it is giving Error
TypeError: loginModal is not a function
angular.module('myApp', ['ui.router', 'ui.bootstrap', 'loginServices','leaveServices']). config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider.
state('home', {
url:'/home',
data: {
requireLogin: false
},
views: {
'': {
templateUrl: 'partials/templates/assets/home.html'
}
}
}).
state('home.about', {
url: '/about',
templateUrl: 'partials/templates/assets/about.html'
}).
state('home.contact', {
url: '/contact',
templateUrl: 'partials/templates/assets/contactUs.html'
}).
state('/login', {
url: '/login',
data: {
requireLogin: false
},
templateUrl: 'partials/login.html',
controller: loginUserController
}).
state('/register', {
url:'/register',
data: {
requireLogin: false
},
templateUrl: 'partials/registerUser.html',
controller: registerController
}).
state('/getAllUsers', {
url: '/getAllUsers',
data: {
requireLogin: false
},
templateUrl: 'partials/getAllUsers.html',
controller: getUsersController
}).
state('/updateUser', {
url : '/updateUser/:id/:name',
data: {
requireLogin: true
},
params: {'id':null, 'name':null},
templateUrl: 'partials/updateUser.html',
controller: updateUserController
}).
state('/userLeave', {
url : '/userLeave:name',
data: {
requireLogin: true
},
params: {'name': null},
templateUrl: 'partials/userLeave.html',
controller: userLeaveController
}).
state('/leaveRequest', {
url : '/leaveRequest',
data: {
requireLogin: true
},
templateUrl: 'partials/leaveRequest.html'
});
}])
.run(function ($rootScope, $state, loginModal) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
var requireLogin = toState.data.requireLogin;
console.log('going to state '+toState.name);
if (requireLogin && typeof $rootScope.currentUser === 'undefined') {
event.preventDefault();
loginModal().then(function () {
return $state.go(toState.name, toParams);
})
.catch(function () {
return $state.go('/login');
});
}
});
})
.factory('loginModal', function ($modal, $rootScope) {
function assignCurrentUser (user) {
$rootScope.currentUser = user;
return user;
}
return function() {
var instance = $modal.open({
templateUrl: 'partials/login.html',
controller: loginUserController
});
return instance.result.then(assignCurrentUser);
}
});
here login controller
loginUserController.$inject = ['$scope','$http', 'loginFactory', '$location', '$state'];
function loginUserController($scope,$http,loginFactory,$location, $state){
$scope.validateLogin = function(name,password){
$http.get("http://localhost:3010/validateLogin?userName="+name+"&password="+password)
.then(function(response) {
if(response.data.length != 0) {
console.log("logged user data is "+JSON.stringify(response.data));
$state.transitionTo('/userLeave', {name: name});
// $scope.$close(response);
}
else
$scope.inValidUser = 'Invalid User';
});
};
$scope.cancel = $scope.$dismiss;
}
Could be because you're using an Angular service which expects a constructor which in turn, should not be returning something.
Try changing to a factory, eg
.factory('loginModal', ...
I want to remove exclamation marks from url state routing like my url is now
http://localhost:3000/#!/auth/register
i just want to remove this "!" marks from url after "#"
Is it possible to do? with mean.io
here is my app.js/system.js
'use strict';
//Setting up route
angular.module('mean').config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
// For unmatched routes:
//$urlRouterProvider.otherwise('/');
var checkLoggedin = function($q, $timeout, $http, $location) {
// Initialize a new promise
var deferred = $q.defer();
// Make an AJAX call to check if the user is logged in
$http.get('/loggedin').success(function(user) {
// Authenticated
if (user !== '0') $timeout(deferred.resolve);
// Not Authenticated
else {
$timeout(deferred.reject);
$location.url('/auth/login');
}
});
return deferred.promise;
};
// console.log($stateProvider);
// states for my app
$stateProvider
.state('tasks', {
url: '/kanban/:projectId/:projectSlug',
templateUrl: 'system/views/index.html',
controller: 'IndexController',
resolve: {
loggedin: checkLoggedin,
onEnter: function($stateParams,$state, $uibModal) {
if ( $stateParams.projectId != "" ) {
updateTopMenu('Kanban','task','#!/kanban/'+$stateParams.projectId+'/'+$stateParams.projectSlug);
updateTopMenu('Schedule','schedule','#!/schedule');
}
}
}
}).state('home',{
url:'/',
templateUrl: 'projects/views/index.html',
controller: 'ProjectController',
resolve:{
loggedin: checkLoggedin
}
}).state('taskEdit',{
url:'/kanban/:projectId/:projectSlug/:taskSlug',
templateUrl: 'system/views/index.html',
controller: 'IndexController',
resolve:{
loggedin: checkLoggedin
}
}).state('taskAdd',{
url: "/task/taskAdd",
onEnter: function($stateParams, $state, $uibModal) {
$uibModal.open({
templateUrl: "system/views/include/model.html",
resolve: {},
controller: function($scope, $state, itemService) {
/*
$scope.state = $state.current;
$scope.params = $stateParams;
$scope.item = itemService.get($stateParams.id);
*/
$scope.ok = function () {
$scope.$close('clicked ok');
};
$scope.dismiss = function () {
$scope.$dismiss('clicked cancel');
};
}
}).result.then(function (result) {
// $scope.$close
alert('result ->' + result);
}, function (result) {
// $scope.$dismiss
return $state.transitionTo("home");
alert('dismiss ->' + result);
}).finally(function () {
// handle finally
return $state.transitionTo("tasks");
});
}
});
}
]).config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('!');
}
]);
You can make some transformation on url with $urlRouterProvider.rule in your config function like this:
$urlRouterProvider.rule(function ($injector, $location) {
var path = $location.path(),
normalized = path.replace('!/', '');
if (path !== normalized) {
return normalized;
}
});
Not sure if this is the best way but it seems to work.
Inspired from: https://ui-router.github.io/docs/1.0.0-alpha.5/classes/url.urlrouterprovider.html
(AngularJS v1.2.28 - angular-ui-router v0.2.13
In my index.html I have the following:
<div class="wrapper" ui-view></div>
In my app.js I have my stateProvider set up as:
$urlRouterProvider.otherwise('/app/search');
$stateProvider.state("app", {
url: '/home',
controller: 'MainCtrl',
templateUrl: 'views/main.html'
}).state('app.search', {
resolve: {
categories: function ($q, $stateParams, LiveOak) {
var deferred = $q.defer();
LiveOak.readMembers('/liveoak/storage/categories', {
success: function (categories) {
deferred.resolve(categories);
},
error: function (error) {
console.error(error);
}
});
return deferred.promise;
}
},
url: '/search',
templateUrl: 'views/search.html',
controller: 'SearchCtrl'
}
).state('app.subjects', {
url: '/subjects/:id',
abstract:true,
templateUrl: '<ui-view/>'
}
).state('app.subjects.default', {
resolve: {
subjects: function ($q, $stateParams, LiveOak) {
var deferred = $q.defer();
var categoryId = $stateParams.id;
var query = {
categoryId : categoryId
};
LiveOak.readMembers('/liveoak/storage/subjects', {
query: query,
success: function (subjects) {
console.log("subjects resolved")
deferred.resolve(subjects);
},
error: function (error) {
console.error(error);
}
});
return deferred.promise;
},
instructors: function ($q, $stateParams, LiveOak) {
}
},
url: '',
templateUrl: 'views/subject.html',
controller: 'SubjectCtrl'
}).state('app.subjects.authors', { //THIS IS NOT RECOGNIZED
resolve: {
authors: function ($q, $stateParams, LiveOak) {
var deferred = $q.defer();
var subjectId = $stateParams.id;
var query = {
query.subjectId : subjectId
};
LiveOak.readMembers('/liveoak/storage/authors', {
query: query,
success: function (authors) {
deferred.resolve(authors);
},
error: function (error) {
console.error(error);
}
}
);
return deferred.promise;
}
},
url: '/subjects/:id/authors/',
templateUrl: '../views/subjects.authors.html',
controller: 'AuthorsCtrl'
}
);
}]);
I am wrestling with the state: app.subjects.authors. Right now app.search and app.subjects work. However, when I try to go the the state: app.subjects.authors it is not even recognized. I set up up a state app.subject as abstract, so hopefully app.subjects.authors wouldn't be overridden by app.subjects. Anyone see anything out of the ordinary?
Thanks for the help!!
My subject.html looks like this:
<div ng-repeat="subject in subjects" class="mdl-cell mdl-cell--4-col">
<a href="#/app/subjects/{{subject.categoryId}}/authors">
<span>{{subject.name}}</span>
</a>
</div>
Just change templateUrl: to template:. You don't need abstract:.
.state('app.subjects', {
url: '/subjects/:id',
template: '<ui-view/>'
})
You shall have:
url: '/authors',
Instead of:
url: '/subjects/:id/authors/',
Because url is relative. So the url of child state is continuation of parent state's url. So authors state will match following url:
/home/subjects/:id/authors
seems like $stateParams is not working.
passing date like this:
$state.go('state2', { someParam : 'broken magic' });
params being ignored on the target state
console.log('state2 params:', $stateParams); // return empty object {}
code:
var app = angular.module('app', [
'ui.router'
]);
app.config(function($stateProvider) {
$stateProvider
.state('state1', {
url: '',
templateUrl: 'state-1.html',
controller : function ($scope, $state, $stateParams) {
$scope.go = function () {
$state.go('state2', { someParam : 'broken magic' });
};
console.log('state1 params:', $stateParams);
}
})
.state('state2', {
url: 'state2',
templateUrl: 'state-2.html',
controller : function ($scope, $state, $stateParams) {
$scope.go = function () {
$state.go('state1', { someOtherParam : 'lazy lizard' });
};
console.log('state2 params:', $stateParams);
}
});
});
Live example can be found here
thank you.
You can't pass arbitrary parameters between states, you need to have them defined as part of your $stateProvider definition. E.g.
$stateProvider
.state('contacts.detail', {
url: "/contacts/:contactId",
templateUrl: 'contacts.detail.html',
controller: function ($stateParams) {
console.log($stateParams);
}
}) ...
The above will output an object with the contactId property defined. If you go to /contacts/42, your $stateParams will be {contactId: 42}.
See the documentation for UI-Router URL Routing for more information.
if you don't want to define your parameter in the url, you must include a params property on the state you are transitioning to. Otherwise the data will be removed from the $stateParams object. The format of the params object is an array of strings in older versions of angular-ui-router; in newer versions it is an object of empty objects:
params: { id: {}, blue: {}}
See this example:
$stateProvider.state('state1', {
url: '',
params: {
id: 0,
blue: ''
},
templateUrl: 'state-1.html',
controller: function($scope, $state, $stateParams) {
$scope.go = function() {
$state.go('state2', {
id: 5,
blue: '#0000FF'
});
};
console.log('state params:', $stateParams);
}
});
Related question:
Parameters for states without URLs in ui-router for AngularJS
Just passing parameters to a state is not enough. You have to define the parameter explicitly by name in the url property of your state.
If you don't do this, ui-router won't know this state is expecting a parameter and the $stateParams object will not be populated like you want.
Here is an example of how you might modify your state to expect a parameter, inject $stateParams, and do something with said parameter:
$stateProvider.state('state1', {
url: '',
templateUrl: 'state-1.html',
controller : function ($scope, $state, $stateParams) {
$scope.params = $stateParams;
$scope.go = function () {
$state.go('state2', { id : 'broken magic' });
};
console.log('state1 params:', $stateParams);
}
})
.state('state2', {
url: 'state2/:id',
templateUrl: 'state-2.html',
controller : function ($scope, $state, $stateParams) {
$scope.params = $stateParams;
$scope.go = function () {
$state.go('state1', { someOtherParam : 'lazy lizard' });
};
console.log('state2 params:', $stateParams);
}
})
Here is a working example of passing state params on jsfiddle.
the solutions above works but for my case I needed to pass query parameter so I dit it like this:
$stateProvider
.state('state1', {
url: '/state1?other',
templateUrl: 'state-1.html',
controller : function ($scope, $state, $stateParams) {
$scope.params = $stateParams;
$scope.go = function () {
$state.go('state2', { someParam : 'broken magic' });
};
console.log('state1 params:', $stateParams);
}
})
.state('state2', {
url: '/state2?someParam',
templateUrl: 'state-2.html',
controller : function ($scope, $state, $stateParams) {
$scope.params = $stateParams;
$scope.go = function () {
$state.go('state1', { other : 'lazy lizard' });
};
console.log('state2 params:', $stateParams);
}
});
Make a transport and use it!
angular_app.factory('$$transport', function($q) {
var transport;
return transport = {
dfr: $q.defer(),
push: function(v) {
return transport.dfr.resolve(v);
},
then: function(s, f) {
if (f == null) {
f = function() {};
}
return transport.dfr.promise.then(function(_s) {
s(_s);
transport.dfr = $q.defer();
return transport.then(s, f);
}, function(_f) {
f(_f);
transport.dfr = $q.defer();
return transport.then(s, f);
});
}
};
});
$stateProvider.state('state1', {
url: '/state1?other',
templateUrl: 'state-1.html',
controller : function ($scope, $state, $$transport) {
$$transport.then(function(s) {
$scope.param = s
console.log('state1 params:', s);
});
$scope.go = function () {
$state.go('state2', { someParam : 'broken magic' });
}
}
})
.state('state2', {
url: '/state2?someParam',
templateUrl: 'state-2.html',
controller : function ($scope, $state, $$transport) {
$scope.go = function () {
$$transport.push({other:'lazy lizard'});
$state.go('state1');
};
}
});