I have the services and within particular time duration if response is come than ok, other wise show error in popup.
Here is my service code:
angular.module('server', [])
.factory('api', function($http) {
var server = "http://myapi-nethealth.azurewebsites.net";
return {
//Login
login : function(formdata) {
return $http({
method: 'POST',
url: server + '/Users/Login',
data: $.param(formdata),
headers: { 'Content-Type' : 'application/x-www-form-urlencoded'},
})
},
};
});
Please tell me how can I use timeout property in services.
Read this post - How to set a global http timeout in AngularJs
Where you can set a timeout for your http calls.
You can inject the above factory in your controller and then make a call with success and error callbacks like below
api.login(formdata)
.success(function(){ alert("success"); })
.error(function(){ alert("error"); });
Related
I'm new to AngularJS and
I needed to know if we can make a jQuery like Ajax call in Angular and wanted to know it's complete syntax,
if anyone could help me making the whole code syntax.
Example in jQuery I could do something like -
$.ajax(
{
url: 'someURL',
type: 'POST',
async: false,
data:
{
something: something,
somethingelse: somethingelse
},
beforeSend: function()
{
$('#someID').addClass('spinner');
},
success: function(response)
{
$('#someID').removeClass('spinner');
console.log(response);
},
complete: function(response)
{
$('#someID').removeClass('spinner');
console.log(response);
},
error: function (errorResp)
{
console.log(errorResp);
}
});
Now here's what I found out on making http call in Angular,
Need help in building the complete syntax, with all possible options -
var req = {
method: 'POST',
url: 'someURL',
headers: {
'Content-Type': undefined
},
data: {
//goes in the Payload, if I'm not wrong
something: 'something'
},
params:{
//goes as Query Params
something: 'something',
somethingElse: 'somethingElse'
}
}
$http(req)
.then(function()
{
//success function
},
function()
{
//Error function
});
now what if I want to attach a spinner on some id in the BeforeSend function like in jQuery and remove the spinner in success,
What is the Angular's way as a like to like for BeforeSend or making the http call async?
Angular even let you control this better :). Two ways can be chosen here:
1. Wrapping $http
You can write for each request with by using a wrapper of $http which will add some methods before and after you made request
app.factory('httpService',function($http){
function beginRequest() {};
function afterRequest() {};
return {
makeRequest: function(requestConfig){
beginRequest();
return $http(requestConfig).then(function(result){
afterRequest(result);
});
}
}
})
Then each time you can call this function to make a request. This is not new.
2. Using interceptor
Angular has a better way to handle for all request. It use a new concept named 'interceptor'. You write your interceptor as a normal service and push one or many interceptors into $http service and depend on type of interceptor, it will be called each time your request happen. Look at this picture to think about interceptor:
Some common task for interceptor can be: Add/remove a loading icon, add some more decorator to your http config such as token key, validate request, validate responded data, recover some request...
Here is example of a interceptor that add a token key into headers of a request
app.service('APIInterceptor', function($rootScope, UserService) {
var service = this;
service.request = function(config) {
var currentUser = UserService.getCurrentUser(),
access_token = currentUser ? currentUser.access_token : null;
if (access_token) {
config.headers.authorization = access_token;
}
return config;
};
service.responseError = function(response) {
return response;
};
})
Then add interceptor to your $http:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('APIInterceptor');
}]);
Now all request will be added a token key to header. cool right?
See here for more information:
there is eveyrthing here to help with your question :https://docs.angularjs.org/api/ng/service/$q http://chariotsolutions.com/blog/post/angularjs-corner-using-promises-q-handle-asynchronous-calls/
$http functions are async by default.
And regarding the beforesend function, you could wrap the http call in a function and add the spinner just before making the call and remove it in the success call back. Something like this,
var makeHttpRequest = function(){
$('#someID').addClass('spinner');
$http(req).then(function(){
$('#someID').removeClass('spinner');
//rest processing for success callback
},function(){
$('#someID').removeClass('spinner');
//Error callback
});
}
The way I have implemented complex get and post in my angular application is as below:
Create a CRUDService as below:
yourApp.service('CRUDService', function ($q, $http) {
this.post = function (value, uri) {
var request = $http({
method: "post",
url: uri,
data: value
});
return request;
}
this.get = function (uri) {
var request = $http({
method: "get",
url: uri
});
return request;
}
});
As you can see this service simply returns a get/post object. Somewhere in my controller I use this service as below:
$('#exampleButton').button("loading"); //set the element in loading/spinning state here
var getObj = CRUDService.get("/api/get/something");
getObj.then(function(data){
//do something
$('#exampleButton').button("reset"); //reset element here
}, function(err){
//handle error
$('#exampleButton').button("loading"); //reset element here
});
$('#exampleButton').button("loading"); //set the element in loading/spinning state here
var postObj = CRUDService.post(postData,"/api/get/something");
postObj.then(function(data){
//do something
$('#exampleButton').button("reset"); //reset element here
}, function(err){
//handle error
$('#exampleButton').button("loading"); //reset element here
});
I hope this helps :)
The http call is async - it returns a promise that you can then handle with the try() and catch() methods. You can simply wrap your calls i.e.
function makeRequest() {
$scope.showSpinner = true;
$http
.get('http://www.example.com')
.then(function (response) {
$scope.showSpinner = false;
})
.catch(function (err) {
$scope.showSpinner = false;
});
}
If you would however like you use familiar syntax akin to jQuery then you can push your own custom interceptors. This will allow you intercept the requests and response and do whatever you want. In the below example we call functions if they are defined.
angular
.module('app', [])
.config(appConfig)
.factory('HttpInterceptors', httpInterceptors)
.controller('MyController', myController);
// app config
appConfig.$inject = ['$httpProvider'];
function appConfig($httpProvider) {
// add out interceptors to the http provider
$httpProvider.interceptors.push('HttpInterceptors');
}
// http interceptor definition
function httpInterceptors() {
return {
request: function(request) {
if (angular.isFunction(request.beforeSend)) {
request.beforeSend();
}
return request;
},
response: function(response) {
if (angular.isFunction(response.config.onComplete)) {
response.config.onComplete();
}
return response;
}
}
}
// controlller
myController.$inject = ['$scope', '$http', '$timeout'];
function myController($scope, $http, $timeout) {
$scope.showSpinner = false;
$http({
method: 'GET',
url: 'https://raw.githubusercontent.com/dart-lang/test/master/LICENSE',
beforeSend: function() {
$scope.showSpinner = true;
},
onComplete: function() {
$timeout(function() {
console.log('done');
$scope.showSpinner = false;
}, 1000);
}})
.then(function(response) {
console.log('success');
})
.catch(function(err) {
console.error('fail');
});
}
.spinner {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<div ng-app='app' ng-controller='MyController'>
<div ng-class='{spinner: showSpinner}'>
Hello World!
</div>
</div>
Im trying to post a api using for my registration page and i have used $HTTP request to post data
it('login page to patient dashboard with existing email and password', function() {
console.log('entering login page')
browser.get('http://localhost:9000/login.html');
browser.executeScript(function(callback) {
var $http;
$http = angular.injector(["ng"]).get("$http");
console.log('http request')
return $http({
url: "http://int.eclinic247.com/reg/create-patient",
method: "post",
data: {"firstName":"jya","lastName":"raq"},
dataType: "json"
}).success(function() {
return callback([true]);
console.log('done')
}).error(function(data, status) {
return callback([false, data, status]);
console.log('oops not done!!!!')
});
})
element(by.model(Objects.locators.passwordBox)).sendKeys(Objects.login.password);
I see that the executeScript block doesnot run and there are no errors too...and the test case passes
Is this the way to post a http request using protractor...Please suggest me the proper to post a data to back-end directly
Any help is much appreciated...Thanks in advance
It's been 3months since I've used angular and I'm loving it. Finished an app using it and now I'm on a code refactoring or improving my code for better practice. I have an Api service.js that used $http and I want to migrate it to using $resource :)
I have here a sample of my api code using $http:
Service.js
authenticatePlayer: function(postData) {
return $http({
method : 'POST',
url : api + 'auth/player',
data : postData,
headers : {'Content-Type' : 'application/json'}
});
},
#Controller.js
Api.authenticatePlayer(postData).then(function (result){
//success
}, function(result) {
//error also this will catch error 400, 401, and 500
});
The above code are working and now here is my first attempt on using $resource:
authenticate: function() {
return $resource(api + "auth/:usertype",
{
typeOfUser : "#usertype" //types can be player, anonymous, admin
},
{
post : { method : "POST" }
}
);
}
#Controller
var postData = {
email : scope.main.email,
password : scope.main.password
};
var loginUser = new Api(postData);
loginUser.$post(); //error T__T
That just how far I get, don't know how to pass a data to my api using $resource from my controller. That just one part of my api call, there's still a bunch of it but for now this will do. :D.
Any help is greatly appreciated.
Thanks
You could try this:
API
authenticate: function(){
return $resource(api+"auth/:usertype",{},post:{method:"POST"});
}
Note: :usertype in URL means that the value of usertype property which you passed into postData will replace the part of URL
Controller
var postData = {email:scope.main.email,password:scope.main.password};
API.authenticate().post({usertype:'player'},postData,function(response){
console.log(response);
});
Or you could fetch response like this:
var response = API.authenticate().post({usertype:'player'},postData);
Hope this is helpful.
I was able to convert most of my existing services to use Restangular. Everything apart from POST is working properly.
Original POST service that works
app.service('APIService', function($http, $q){
...
this.post = function(api, route, params){
var d = $q.defer();
$http({
url : base_urls[api] + route,
method : 'POST',
data : params,
withCredentials: true,
useXDomain : true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function(data){
d.resolve(data);
try{
toastr.success(toastMsg[route].win, 'Success');
} catch(err){}
}).error(function(data){
d.reject(data);
try{
toastr.error(toastMsg[route].fail, 'Whoops');
} catch(err){}
});
return d.promise;
}
});
Which is used like this:
app.controller('AuthController', function($scope, APIService){
$scope.login = function(username_or_email, password, redirectUrl){
APIService.post('root', '/login', {
'username_or_email' : username_or_email,
'password' : password
}).then(function(r){
if(r.success){
window.location = redirectUrl;
}else
{
// handle this
}
});
};
});
Conversion to Restangular
app.controller('AuthController', function ($scope, toastrFactory, Restangular) {
$scope.login = function (username_or_email, password, redirectUrl) {
var login = Restangular.one('auth'),
creds = {
'username_or_email': username_or_email,
'password': password
};
login.post('login', creds).then(function (r) {
window.location = redirectUrl || '/profile';
}, function () {
toastrFactory.error(['Error', 'Login not successful'])
})
};
});
The above fails the pre-flight OPTIONS pass, and gives up. What is the difference between my original service and the Restangular call I'm trying to use?
Worth noting I did set default config params for Restangular (to mirror the original service)
RestangularProvider.setBaseUrl('https://dev.foo.com/');
RestangularProvider.setDefaultHttpFields({
withCredentials: true,
useXDomain : true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
What's strange is my Restangular GETs that require credentials on https:// WORK, and successfully pass the OPTIONS phase, and manage to send cookie data.
Any help is appreciated. Thanks.
I'm not sure about the actual route you are trying to reach, but the Restangular.one('auth') seems like you'd need to define the resource identifier (eg. POST /auth/123?username_or_email=moi).
If you're trying to reach POST /auth?username_or_email=moi (with your cred in the HTTP parameters), then try Restangular.all('auth').
If this didn't solve the problem, please provide the URI you're seeing in the browser's network inspector along with the URI you'd want to reach.
I try to make an application with PhoneGap and AngularJS that can be used online and offline (for Android device).
I want to get a list of people from the local database if the device is offline, and from a web service, using $http, if the device is online. But when the device is online, it doesn't work, web service isn't called.
I think the problem is PhoneGap asynchronous method. Indeed, in offline mode, it works but i need to use $scope.$apply to update my view. But that doesn't work for $http...
Does someone know how to use $http in asynchronous method?
function ListCtrl ($scope, $http){
$scope.list = [];
$scope.Id = 2;
$scope.init = function(){
document.addEventListener("deviceready", getList, false);
}
$scope.getAll = function(){
$http({
url: 'http://10.0.0.2:63414/myWebMethod/' + $scope.Id,
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).success(function(data) {
$scope.list = data;
});
}
function getList(){
var db = window.openDatabase("Database", "1.0", "list", 200000);
var network = navigator.connection.type;
if (network == "none"){
// local database transaction works fine
} else {
$scope.getAll();
}
$scope.$apply();
}
$scope.init();
}
In the success callback you also have to trigger the digest with $scope.$apply();
$http({
url: 'http://10.0.0.2:63414/myWebMethod/' + $scope.Id,
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).success(function(data) {
$scope.list = data;
$scope.$apply();
});
$http requests are asynchronous, so before you get any response from your request the program will keep executing and $scope.$apply() that you put after the if (network == "none") statement will run for nothing (you can remove it).
The PhoneGap query is working because you are using $scope.$apply() in it's callback, and you have to do the same in the $http success callback.