Below is my code snippet where i'm trying to use uimodal to display the user detail along with additional detail.
I'm failing to bind the response data to uimodal, Kindly help to resolve this.
$scope.selectedUserData = '';
$scope.edituser = function (user) {
usereditService.resp(size.userid, function (response) {
if (response != false) {
console.log(response[0]);//Specific user details object from API
selectedUserData = response[0];
}
else {
console.log('no user found');
}
});
$scope.modalInstance = $uibModal.open({
animation: false,
backdrop: 'static',
templateUrl: '/_views/_editUser.html',
controller: 'userController',
size: size,
resolve: {
selectedData: function () {
return $scope.selectedUserData;
}
},
controller: function($scope, selectedData) {
$scope.editobj = selectedData;
}
});
modalInstance.result.then(function (response) {
$scope.selected = response;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
The data is coming from async response, so can't get that ajax response data as soon as your requested for it.
You need to follow promise pattern in that case, and return the data in promise chain patter from your resolve's selectedData function.
//assuming usereditService.resp is returning promise object
//it it doesn't returning promise object, you need to create it by custom promise using $q
var userDataPromise = usereditService.resp(size.userid).then(function (response) {
if (response != false) {
console.log(response[0]);//Specific user details object from API
selectedUserData = response[0];
return selectedUserData;
}
else {
console.log('no user found');
return 'no user found';
}
}, function(error){
console.log();
return 'no user found';
});
$scope.modalInstance = $uibModal.open({
animation: false,
backdrop: 'static',
templateUrl: '/_views/_editUser.html',
controller: 'userController',
size: size,
resolve: {
selectedData: function () {
//returning response object here as a promise.
return userDataPromise;
}
},
controller: function($scope, selectedData) {
$scope.editobj = selectedData;
}
});
Related
In my code, I define the following two routes:
$routeProvider.when('/problem/report', {
templateUrl: '/app/management/problem/reportAProblem.html',
controller: 'reportAProblemCtrl',
resolve: {
authorized: function($http, $location) {
var path = $location.path();
return $http.get('/svc/authorize/view?urlPath=' + path).then(function(response) {
var data = response.data;
if (response.data.result === 'NOT_AUTHORIZED') {
throw "NOT_AUTHORIZED";
}
return data;
})
}
}
});
$routeProvider.when('/problem', {
templateUrl: '/app/management/problem/problem.tmpl.html',
controller: 'problemCtrl',
resolve: {
authorized: ['$authorization', function($authorization) {
$authorization.authorize();
}]
}
});
The first case seems to work. However, the second case has had the function refactored into a Service, and AngularJS does not seem to be waiting for the Promise to resolve before displaying the page.
The refactored code looks like the following:
angular.module('authorization', [])
.factory('$authorization', ['$http', '$location',function($http, $location) {
var $authorization = {};
$authorization.authorize = function() {
var path = $location.path();
return $http.get('/svc/authorize/view?urlPath=' + path).then(function(response) {
var data = response.data;
if (response.data.result === 'NOT_AUTHORIZED') {
throw "NOT_AUTHORIZED";
}
return data;
});
}
return $authorization;
}]);
Can anyone tell me why the second case above doesn't wait for the promise to resolve before displaying the page?
Add return:
authorized: ['$authorization', function($authorization) { **return** $authorization.authorize(); }]
In my code, I define the following two routes:
$routeProvider.when('/problem/report', {
templateUrl: '/app/management/problem/reportAProblem.html',
controller: 'reportAProblemCtrl',
resolve: {
authorized: function($http, $location) {
var path = $location.path();
return $http.get('/svc/authorize/view?urlPath=' + path).then(function(response) {
var data = response.data;
if (response.data.result === 'NOT_AUTHORIZED') {
throw "NOT_AUTHORIZED";
}
return data;
})
}
}
});
$routeProvider.when('/problem', {
templateUrl: '/app/management/problem/problem.tmpl.html',
controller: 'problemCtrl',
resolve: {
authorized: ['$authorization', function($authorization) {
$authorization.authorize();
}]
}
});
The first case seems to work. However, the second case has had the function refactored into a Service, and AngularJS does not seem to be waiting for the Promise to resolve before displaying the page.
The refactored code looks like the following:
angular.module('authorization', [])
.factory('$authorization', ['$http', '$location',function($http, $location) {
var $authorization = {};
$authorization.authorize = function() {
var path = $location.path();
return $http.get('/svc/authorize/view?urlPath=' + path).then(function(response) {
var data = response.data;
if (response.data.result === 'NOT_AUTHORIZED') {
throw "NOT_AUTHORIZED";
}
return data;
});
}
return $authorization;
}]);
Can anyone tell me why the second case above doesn't wait for the promise to resolve before displaying the page?
Add return:
authorized: ['$authorization', function($authorization) { **return** $authorization.authorize(); }]
What Im aiming is that I will have different tabs layout for different users
like patient and doctors
in my controller, I store the logged user in $rootScope.currentUser like this
$auth.login(credentials).then(function(data) {
return $http.get(CONSTANTS.LINK+'/authenticate/user');
}, function(data) {
var alertPopup = $ionicPopup.alert({
title: 'Error Logging in',
template: 'Invalid Credentials'
});
alertPopup.then(function(res) {
});
}).then(function(response) {
var user = JSON.stringify(response.data.user);
localStorage.setItem('user', user);
$rootScope.authenticated = true;
$rootScope.currentUser = response.data.user;
$state.go('tabs.home');
});;
Now this is my app.js. Nothing happens. am i Doing it right?
The $rootscope.currentUser is also returning undefined when i try console.log($rootScope.currentUser);
.state('tabs', {
url: '/tab',
templateUrl: function ($rootScope) {
if($rootScope.currentUser.role == 'Patient') {
return 'templates/tabs.html';
} else if ($rootScope.currentUser.role == 'Doctor') {
return 'templates/tabs-doctors.html';
}
},
abstract: true,
})
Since I was storing the user data in local storage when he logs in, I used that data to check the role of the user.
.state('tabs', {
url: '/tab',
templateUrl: function () {
var user = JSON.parse(localStorage.getItem('user'));
role = user.role;
if(role == 'Patient') {
return 'templates/tabs.html';
} else if (role == 'Doctor') {
return 'templates/tabs2.html';
} else {
return 'templates/tabs.html';
}
},
abstract: true,
})
How do I prevent a state change for a specific "to" state in ui-router (is it using onEnter?) assuming I have this route:
.state('auth.confirm', {
url: '/confirm/:resetToken',
template: '<confirm-page></confirm-page>',
data: { pageTitle: 'Confirm Reset', specialClass: 'gray-bg' }
})
and this service with this promise-based function:
validateResetToken: function(resetToken) {
var self = this;
var deferred = $q.defer();
$http.post(AppConstants.hostRootUrl + '/auth/reset/validate', { resetToken: resetToken })
.then(function(response) {
if(response.data && response.data.success) {
// if we got a 200 return and it indicates success in the response, resolve
self.message = 'Success';
deferred.resolve(self.message);
}
else if (response.data && !response.data.success && response.data.error) {
// if we got a 200 return, but success is falsey and there's an error message, reject with that message
self.message = response.data.error;
deferred.reject(self.message);
}
else {
// error with generic message
self.message = 'Unknown response. Contact administrator.';
deferred.reject(self.message);
}
}, function(errPost) {
if (errPost.data && errPost.data.error) {
self.message = errPost.data.error;
deferred.reject(self.message);
}
else {
self.message = 'Could not connect.';
deferred.reject(self.message);
}
});
return deferred.promise;
},
For posterity (and Googlers) sake, Alon Eitan made me take a second look at my resolve approach, and I realized that my addition of the catch() was causing the rejected promise to not percolate up. This final code works:
.state('auth.confirm', {
url: '/confirm/:resetToken',
template: '<confirm-page></confirm-page>',
data: { pageTitle: 'Confirm Reset', specialClass: 'gray-bg' },
resolve: {
validated: function($q, $stateParams, AuthService, toastr) {
//$log.log('auth.confirm resolve $stateParams',$stateParams);
return AuthService.validateResetToken($stateParams.resetToken).catch(function(validateErr) {
toastr.error(validateErr, 'Blocked', {closeButton: true});
return $q.reject(validateErr);
});
}
}
})
You can create a rule as in https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-create-rules-to-prevent-access-to-a-state
Adapt their example:
app.config(function($stateProvider) {
$stateProvider.state('privatePage', {
data: {
rule: function(token) {
return validateResetToken(token)
}
});
});
app.run(function($rootScope, $state, $stateParams) {
$rootScope.$on('$stateChangeStart', function(e, to) {
if (!angular.isFunction(to.data.rule)) return;
var result = to.data.rule($stateParams.resetToken);
if (result && result.to) {
e.preventDefault();
// Optionally set option.notify to false if you don't want
// to retrigger another $stateChangeStart event
$state.go(result.to, result.params, {notify: false});
}
});
});
I want to load two APIs before page is going to load For it i have used the following code in $stateProvider
.state('admin-panel.default.jobadd', {
url: '/jobadd/:jobID',
templateUrl: 'app/search/jobadd.tmpl.html',
controller: 'JobaddController',
resolve: {
jobAdd: ['Search', '$stateParams','$q', function(Search,$stateParams,$q) { //Search is service
var jobAdd = Search.jobAdd($stateParams.jobID);
var isApplied = Search.is_job_applied($stateParams.jobID);
jobAdd.$promise.then(function(response) {console.log('Resource 1 data loaded!')});
isApplied.$promise.then(function(response) {console.log('Resource 2 data loaded!')});
return $q.all([jobAdd.$promise, isApplied.$promise]);
}]
},
data: {
requireLogin: true
}
});
})
But it's not give the data when injects to the controller, page seems as blank
my controller code is
.controller('JobaddController', function ($scope, $mdDialog, $state, jobAdd, Profile) {
$scope.jobs = jobAdd[0];
$scope.benifits = jobAdd[0].benifits;
if($scope.jobs.short_listed == 1)
$scope.jobs.flag = true;
else
$scope.jobs.flag = false;
$scope.checkShortList= function(job){
if(job.flag){
Profile.rmShortList(job.short_list_id);
job.flag = false;
}
else{
if(job.short_list_id === null){
Profile.addNewShortList(job.id).then(function(response){
job.short_list_id = response.short_list_id;
});
}
else
Profile.addShortList(job.short_list_id,job.id);
job.flag = true;
}
};
$scope.companyModal = function(ev) {
$mdDialog.show({
controller: 'CompanyDetailsController',
templateUrl: 'app/search/company-details.tmpl.html',
parent: angular.element(document.body),
targetEvent: ev,
})
.then(function(answer) {
$scope.alert = 'You said the information was "' + answer + '".';
}, function() {
$scope.alert = 'You cancelled the dialog.';
});
};
$scope.applyModal = function(ev) {
$mdDialog.show({
controller: 'ApplyController',
templateUrl: 'app/search/apply.tmpl.html',
locals: { Jobid: $scope.jobs.id },
parent: angular.element(document.body),
targetEvent: ev,
resolve: {
shortProfile: ['Profile', function(Profile) {
return Profile.shortProfile();
}]
},
})
.then(function(answer) {
$scope.alert = 'You said the information was "' + answer + '".';
}, function() {
$scope.alert = 'You cancelled the dialog.';
});
};
var container = angular.element(document.getElementById('container'));
var section2 = angular.element(document.getElementById('section-2'));
$scope.toTheTop = function() {
container.scrollTop(0, 5000);
};
$scope.toSection2 = function() {
container.scrollTo(section2, 0, 1000);
};
})
in service code
.service('Search', [ '$http', '$q', 'API',
function($http, $q, API) {
var data = '';
this.jobAdd = function(job_id) {
var def = $q.defer();
$http({
url: API.url+'get_job_add_detail?job_id=' + job_id,
method: "GET"
}).success(function(response) {
if(response.status == 'Success'){
data = response.data;
def.resolve(data);
}
}).error(function(response) {
console.log (response);
if(response.status == 'Failed'){
data = response.msg;
def.reject(data);
}
});
return def.promise;
}
this.isJobApplied = function(job_id) {
var def = $q.defer();
$http({
url: API.url+'is_job_applied?job_id='+job_id,
method: "GET",
}).success(function(response) {
if(response.status == 'Success'){
data = response.data;
def.resolve(data);
}
}).error(function(response) {
console.log (response);
if(response.status == 'Failed'){
data = response.msg;
def.reject(data);
}
});
return def.promise;
}
}]);
What's the wrong here?? how to attach more than on service in $state resolve?
simply you can for more than one service.
resolve: {
jobAdd: ['Search', '$stateParams', function(Search,$stateParams) {
return Search.jobAdd($stateParams.jobID);
}],
isApplied: ['Search', '$stateParams', function(Search,$stateParams) {
return Search.isJobApplied($stateParams.jobID);
}]
}