whats wrong in this $http request in angular? - angularjs

Here is the code :
(function () {
angular.module('PillApp').factory('AuthFactory',
['$q', '$timeout', '$http', 'Flash', '$state',
function ($q, $timeout, $http, Flash, $state) {
// create user variable
var user = null;
// return available functions for use in the controllers
return ({
isLoggedIn: isLoggedIn,
getUserStatus: getUserStatus,
login: login,
logout: logout,
register: register
});
function isLoggedIn() {
if(user) {
return true;
} else {
return false;
}
}
function getUserStatus(callback) {
$http.get('/status/user')
// handle success
.then(function (data) {
//console.log(JSON.stringify(data));
if(data.data !== ''){
user = true;
callback(user);
} else {
user = false;
callback(user);
}
});
}
function login(userProfile) {
// create a new instance of deferred
var deferred = $q.defer();
console.log("Authentication Service - to send login to server");
// send a post request to the server
$http.post('/login',
userProfile)
// handle success
.success(function (data, status) {
console.log("Authentication response received");
if(status == 200){
getUserStatus(function(result){
if(result){
deferred.resolve();
$state.go('A');
}else{
deferred.reject();
Flash.create('danger', "Ooops having issue logging in!", 0, {class: 'custom-class', id: 'custom-id'}, true);
$state.go('A');
}
});
} else {
user = false;
Flash.clear();
Flash.create('danger', "Ooops having issue logging in!", 0, {class: 'custom-class', id: 'custom-id'}, true);
deferred.reject();
}
})
// handle error
.error(function (data) {
console.log("Authentication error - any flash messsage?");
user = false;
Flash.clear();
Flash.create('danger', "Ooops having issue logging in!", 0, {class: 'custom-class', id: 'custom-id'}, true);
deferred.reject();
});
// return promise object
return deferred.promise;
}
function logout() {
// create a new instance of deferred
var deferred = $q.defer();
// send a get request to the server
$http.get('/logout')
// handle success
.success(function (data) {
user = false;
deferred.resolve();
})
// handle error
.error(function (data) {
user = false;
deferred.reject();
});
// return promise object
return deferred.promise;
}
function register(username, password) {
// create a new instance of deferred
var deferred = $q.defer();
console.log("Sending registration to server");
// send a post request to the server
$http.post('/register',
{username: username, password: password})
// handle success
.success(function (data, status) {
if(status){
console.log('Registration successful', data, status);
deferred.resolve();
} else {
console.log('Registration unsuccessful', data);
Flash.closeFlash();
Flash.create('danger', "Can't register with us!", 0, {class: 'custom-class', id: 'custom-id'}, true);
deferred.reject();
}
})
// handle error
.error(function (data) {
console.log('Registration error', data);
Flash.clear();
Flash.create('danger', "Ooops something went wrong!", 0, {class: 'custom-class', id: 'custom-id'}, true);
deferred.reject();
});
// return promise object
return deferred.promise;
}
}]);
})();
ERROR :
angular.js:14324 TypeError: $http.post(...).then is not a function
at Object.login (http://ec2-52-77-252-229.ap-southeast-1.compute.amazonaws.com:3001/services/auth.factory.js:55:22)
at AppCtrl.vm.login (http://ec2-52-77-252-229.ap-southeast-1.compute.amazonaws.com:3001/app.controller.js:35:25)
at fn (eval at compile (http://ec2-52-77-252-229.ap-southeast-1.compute.amazonaws.com:3001/bower_components/angular/angular.min.js:236:285), <anonymous>:4:167)
at e (http://ec2-52-77-252-229.ap-southeast-1.compute.amazonaws.com:3001/bower_components/angular/angular.min.js:281:195)
I tried $http.post().success also and it gives error like success is not defined
Than i tried $http.post().then also and it gives error like then is not defined
I have injected $http in a right way.it worked on localhost but during production it gives this kind of errors.

You need to define functions containing http post directive in this manner :
$scope.getUserCallback = function (callback) {
$http.get('/status/user')
// handle success
.then(function (data) {
//console.log(JSON.stringify(data));
if(data.data !== ''){
user = true;
callback(user);
} else {
user = false;
callback(user);
}
});
};
then you can call it from inside the script wherever required as
$scope.getUserCallback();
and from an html element like this
<my element ng-click="getUserCallback()"></my element>

I think the $http.post call is failing due to CORS. You may need to enable CORS or send the appropriate HTTP headers in your request. The error you are getting because the $http.post is not returning the expected object which can execute the next success or then methods.
It would work correctly on your localhost as there is no CORS restriction in local development environment.

Related

Can't read header parameters from WebGate response using angularjs

For example this is my VM WARE WEBGATE login page.
After entering Valid Credentials it will Valid Under OAM (oracle access manager) and it will return headers in response.
Now, If the user is valid it will redirect to another page.
But, I can't see the header parameters in response what the WebGate returning
This is my Code:
app.factory('mainHttpInterceptor' ,
function($rootScope, $q, $location) {`enter code here`
console.log("in the authInterceptor------000000");
return{
request:function(config) {
console.log(config.headers);
return config;
},
response: function(response){
/* if (typeof response.headers != null) {
console.log(response.headers);
return response;
} */
console.log('in the hhtp interceptor');
$httpProvider.defaults.headers.common['Access-Control-Allow-Headers']= true;
console.log(response.headers());
console.log(response);
return response;
},
responseError: function(rejection){
console.log('Failed with', rejection.status, 'status');
if( rejection.status ==403){
$location.url('/login');
}
else if( rejection.status ==404){
console.log("nothing is there----------->");
/*$state.go('login');*/
}
return $q.reject(rejection);
}
};
})
app.config(['$httpProvider',function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
/*Access-Control-Allow-Credentials == true;*/
$httpProvider.defaults.headers.common['Access-Control-Allow-Headers'] = true;
$httpProvider.interceptors.push('mainHttpInterceptor');
}]);
What, Should i do to to get those header parameters into my code.

ng-show attribut causes html block blinking (beginner)

On my login page, when I enter wrong credentials (login/pass), an error message is displayed in red.
In login.html :
<div class="alert alert-danger" ng-show="authenticationError"
translate="login.messages.error.authentication">
<strong></strong>
</div>
If I set ng-show="true" explicitely, The message is persistent on the screen ; (fortunately).
The problem comes when ng-show is dynamic (with authenticationError variable)
When this variable is set to true, then the error message appears but left 1 second on the screen and then disappear.
Behind the scene (controller + service) :
login.controller.js :
$scope.login = function () {
// event.preventDefault();
Auth.login({
username: $scope.username,
password: $scope.password,
rememberMe: $scope.rememberMe
}).then(function () {
$scope.authenticationError = false;
// if()
if ($rootScope.previousStateName === 'register') {
$state.go('home');
} else {
$rootScope.back();
}
}).catch(function () {
$scope.authenticationError = true;
});
};
auth.service.js :
angular.module('tessicommunicationApp')
.factory('Auth', function Auth($rootScope, $state, $q, $translate, Principal, AuthServerProvider, Account, Register, Activate, Password, PasswordResetInit, PasswordResetFinish) {
return {
login: function (credentials, callback) {
var cb = callback || angular.noop;
var deferred = $q.defer();
console.log("login ...");
AuthServerProvider.login(credentials).then(function (data) {
// retrieve the logged account information
Principal.identity(true).then(function(account) {
// After the login the language will be changed to
// the language selected by the user during his registration
$translate.use(account.langKey).then(function(){
$translate.refresh();
});
deferred.resolve(data);
});
return cb();
}).catch(function (err) {
this.logout();
deferred.reject(err);
console.log("erreur login !");
return cb(err);
}.bind(this));
return deferred.promise;
},
auth.session.service.js :
angular
.module('tessicommunicationApp')
.factory(
'AuthServerProvider',
function loginService($http, localStorageService, $window, $state, $cookies) {
return {
login : function(credentials) {
var data = 'j_username='
+ encodeURIComponent(credentials.username)
+ '&j_password='
+ encodeURIComponent(credentials.password)
+ '&remember-me=' + credentials.rememberMe
+ '&submit=Login';
return $http
.post(
'api/authentication',
data,
{
headers : {
'Content-Type' : 'application/x-www-form-urlencoded'
}
}).success(function(response) {
return response;
});
},
Tell me if you need more code.
The context is :
1) I need to debug this ticket.
2) I didn't code anything of this web application (especially front-end part)
3) I almost have NO knowledges in AngularJS (just theory a little).
I wish you will help me to solve my first ticket :).*
Aren't you missing a parenthesis and extra parenthesis at the end of the statement here:
}).catch(function (err) {
this.logout();
deferred.reject(err);
console.log("erreur login !");
return cb(err);
}.bind(this));// <-- missing parenthesis
It should be like:
}).catch(function (err) {
this.logout();
deferred.reject(err);
console.log("erreur login !");
return cb(err);
}).bind(this);
Something else you can try when suspect about changes occurring without you know is monitoring the variable change with a $watch like:
$scope.countChange = 0;
$scope.$watch('authenticationError', function(newValue, oldValue) {
$scope.countChange = $scope.countChange + 1;
console.log('Change count :',$scope.countChange , ' New Value =', newValue );
});

AngularJS get value from service function

I have a problem with getting value from service in my controller.
I get the value from API using service:
angular.module('app').factory('service',
['$q', '$rootScope', '$timeout', '$http',
function ($q, $rootScope, $timeout, $http) {
// create user variable
var user = null;
// return available functions for use in the controllers
return ({
isLoggedIn: isLoggedIn,
getUserStatus: getUserStatus,
login: login,
getEmail: getEmail
});
function isLoggedIn() {
if(user) {
return true;
} else {
return false;
}
}
function getUserStatus() {
return $http.get('/user/status')
// handle success
.success(function (data) {
if(data.status){
user = true;
} else {
user = false;
}
})
// handle error
.error(function (data) {
user = false;
});
}
function login(username, password) {
// create a new instance of deferred
var deferred = $q.defer();
// send a post request to the server
$http.post('/user/login',
{username: username, password: password})
// handle success
.success(function (data, status) {
if(status === 200 && data.status){
user = true;
deferred.resolve();
} else {
user = false;
deferred.reject();
}
})
// handle error
.error(function (data) {
user = false;
deferred.reject();
});
// return promise object
return deferred.promise;
}
function getEmail() {
// create a new instance of deferred
var deferred = $q.defer();
$http.get('/email/'+$rootScope.username)
.success(function (data) {
console.log(data);
deferred.resolve();
})
.error(function (data) {
deferred.reject();
})
return deferred.promise;
}
}]);
and I'm trying to get and use value in the controller:
angular.module('app')
.controller('myController', ['$rootScope', '$scope', '$state', '$http', '$q', 'service', function ($rootScope, $scope, $state, $http, $q, service) {
$scope.email;
$scope.getEmail = function() {
// call getEmailFromDB from service
service.getEmail()
// handle success
.then(function (data) {
$scope.email = data; //here I got undefined
console.log($scope.email);
})
// handle error
.catch(function () {
$scope.error = true;
$scope.errorMessage = "wrong#mail.com";
});
};
$scope.getEmail();
}]);
but in the controller there is undefined value.
In my console:
Regarding the documentation of $q, I use then() function in service and controller.
Does anybody know where is the problem?
you forgot to send your result in your service like this
deferred.resolve(data);
In your code you are not returning anything with the promise, to do that you must call deferred.resolve(data) or deferred.reject(data).
Instead of creating a deferred object, you can simply return the $http request.
Example:
function getEmail() {
return $http.get('/email/'+$rootScope.username).then(
function success(data){
console.log(data);
return data;
},
function error(data){
console.error(data);
}
);
}
Also notice that .success() and .error() are deprecated, you should use .then() and pass the success and error functions.

Getting Cannot read property 'then' of undefined when using .fromFnPromise in angular-datatables

//the controller that creates the datatable
app.controller('AdminListCtrl', function ($scope, $compile, DTOptionsBuilder, DTColumnBuilder, adminService) {
var vm = this;
function stateChange(iColumn, bVisible) {
console.log('The column', iColumn, ' has changed its status to', bVisible);
}
//vm.dtOptions = DTOptionsBuilder.fromSource('http://localhost/api-v1/admin')
vm.dtOptions = DTOptionsBuilder.fromFnPromise(function() {
return adminService.loadAdmin();
})
.withPaginationType('full_numbers')
.withOption('createdRow', createdRow)
// Add Bootstrap compatibility
.withBootstrap()
// Active ColVis plugin
.withColVis()
// Add a state change function
.withColVisStateChange(stateChange)
// Exclude the last column from the list
.withColVisOption('aiExclude', [2])
// Add Table tools compatibility
.withTableTools('scripts/vendor/datatables/TableTools/swf/copy_csv_xls_pdf.swf')
.withTableToolsButtons([
'copy',
'print', {
'sExtends': 'collection',
'sButtonText': 'Save',
'aButtons': ['csv', 'xls', 'pdf']
}
]);
//adminService to request for all administrators
app.factory('adminService', ['ApiService', function (ApiService) {
return {
loadAdmin: function () {
ApiService.get("admin").then(function (response) {
if (response) {
if (response.success === true) {
return response;
}else{
console.log(response);
}
}else {
console.log('error request ');
}
});
}
};
}]);
//apiservice to interact with api
app.factory('ApiService', function ($http, $q, $localStorage) {
return {
get: function (apiresource) {
var returnData = $q.defer();
$http({
url: api + apiresource,
method: 'GET',
headers: {"Auth-Token": $localStorage.user_data.auth_token}
})
.success(function (data) {
returnData.resolve(data);
})
.error(function (error) {
returnData.resolve();
});
return returnData.promise;
}};
});`enter code here`
When ever I am in that view it throws this errorCannot read property 'then' of undefined. I am following examples from these two sources
http://www.revillweb.com/angularjs-by-example/4-sharing-data-with-angularjs-services/
http://l-lin.github.io/angular-datatables/#/withPromise
You need to return promise object (result of ApiService.get("admin") call) from loadAdmin method.
Also make sure you don't "swallow" rejections inside of the then (in console.log branches) - what happens when you unintentionally handle errors by not passing it further. For this return rejected promise or simply throw error, so that rejection will propagate further down the promise chain:
app.factory('adminService', ['ApiService', function (ApiService) {
return {
loadAdmin: function () {
return ApiService.get("admin").then(function (response) {
if (response) {
if (response.success === true) {
return response;
} else{
console.log(response);
throw response;
// or custom error object: throw {message: 'Error loadAdmin', response}
}
} else {
console.log('error request ');
throw new Error('error request');
}
});
}
};
}]);

How do I test an $httpBackend POST error state with AngularJS / Karma?

I'm trying to write a unit test for my Angular Service and here's a function in the service:
login = function(authObject) {
deferred = $q.defer();
$http({
url: '/api/v1/session/create',
method: 'POST',
data: authObject
}).success(function(response) {
var user;
if (response.status === 'ok' && response.user && response.authenticated === true) {
user = response.user;
}
return deferred.resolve(response);
}).error(function(data) {
deferred.reject(data);
return $state.go('api_error');
});
return deferred.promise;
};
I can successfully test the success case with something like:
it('should go to the api error state', function() {
var authObject;
authObject = {
username: 'a#b.com',
password: 'c'
};
$httpBackend.expectPOST('/api/v1/session/create').respond(someData);
userService.login(authObject).then(function(response) {
return console.log("not error", response);
}, function(response) {
return console.log("error", response);
});
return expect($state.go).toHaveBeenCalledWith('api_error');
});
That works fine, however if I do:
$httpBackend.expectPOST('/api/v1/session/create').respond(500, 'error');, then the error case doesn't get called. What am I doing wrong?
In order for your .then() error callback to be called, the previous promise in the chain should result in error (e.g. throw an Exception) or be rejected.
Returning 500 will cause the error callback in your login() method to be called, but since that callback neither throws an Error nor gets rejected, your chained error callback won't be called.
E.g. changing:
}).error(function(data) {
deferred.reject(data);
return $state.go('api_error');
});
to:
}).error(function(data) {
return deferred.reject(data);
//return $state.go('api_error');
});
would work (but it doesn't do what you want :D).
I am not familiar with ui-router, but in this case it could be possible that $state.go() aborts the current execution chain, so I am not sure the following would work:
}).error(function(data) {
$state.go('api_error');
return deferred.reject(data);
});

Resources