Calling RESTful apis through ajax and angular js - javascript

If the URL that is to be hit has to be passed variables i.e.
API.openweathermap.org/data/2.5/forecast/city?name=[random_city_name]&APPID=[key_value],
then what is better to use ajax or angular js.
If I am using ajax then how am I supposed to pass the variable? I am a newbie in this. So, need your help.

Your url seems to have request parameters and assuming you are using angular1
For this, you can use
$http({
method: 'GET',
url: url,
headers: {},
params : {}
})
Put your parameters as a map and $http will take care of creating an url.
Refer $http documentation here

what is better to use ajax or angular js
You can't compare as AJAX provides a way to communicate (send requests and get responses) with the server asynchronously and AngularJS used AJAX to extends the 2-way data binding.
To accomplish the above situation we can use Angular $http service.
var baseUrl = API.openweathermap.org/data/2.5/forecast/city;
var method = 'GET';
var data = {};
var params = {
"name":cityName,
"APPID":key_value
};
$http({
method: method,
url: baseUrl,
params : params,
data : data
}).then(function mySucces(response) {
$scope.data = response.data;
}, function myError(response) {
$scope.data = response.statusText;
});

You can use angular $http service and pass your params like below.
var UserInfo = function() {
$scope.userID = "1111";
var req ={
"method":"GET",
"url": someURL + $scope.userID,
"withCredentials":true
};
$http(req).then(function(response) {
alert('success');
}, function(response) {
alert('error');
});
};

Related

AngularJS - Dynamic URL with ID

config.js
angular.module('config', []).constant('ENV',
{
name: 'My Angular Project',
apiEndPoint: 'http://SOMEIP/myServer', //API host,
adminUrl:'/admin/regionid/site/siteid/admin/regionid', //endpoint
loginUrl:'/login/regionid/site/siteid/device'
});
controller.js
this.userLogin = function(username, password) {
var adminServicePath = ENV.apiEndPoint + ENV.adminUrl
//final url = http://SOMEIP/myServer/admin/1/site/1/admin/1
var loginServicePath = ENV.apiEndPoint + ENV.loginUrl
//final url = http://SOMEIP/myServer/login/2/site/2/device
return $http({
method: 'POST',
url: adminServicePath,
headers: {
"Authorization": "Basic ",
"Content-Type": "application/x-www-form-urlencoded"
}
})
};
Here I am appending API with endpoint to form a complete URL. My issue is regiondid and siteid are dynamic. After user logs in, one REST API request will fetch siteid and regionid in response.
How do I dynamically replace siteid and regionid in URL with ID's
received in API response? After receiving id's in response, call a function that replaces the value.
You can use the String.prototype.replace(substr, newsubstr)
You can keep regionID instead of ?
var ENV = {
name: 'My Angular Project',
apiEndPoint: 'http://SOMEIP/myServer', //API host,
adminUrl: '/admin/?/site/?/admin/?', //endpoint
loginUrl: '/login/?/site/?/device'
};
var adminServicePath = ENV.apiEndPoint + ENV.adminUrl.replace("?", 1).replace("?", 1).replace("?", 1);
console.log("Final url admin : " + adminServicePath);
var loginServicePath = ENV.apiEndPoint + ENV.loginUrl.replace("?", 2).replace("?", 2);
console.log("Final url login : " + loginServicePath);
instead of constant, you can use value.
angular.module('config', []).value('ENV',
{
name: 'My Angular Project',
apiEndPoint: '', //API host,
adminUrl:'', //endpoint
loginUrl:''
});
Inject ENV and set all values after API call.
ENV.name = xyz;
ENV.apiEndPoint = xyz;
ENV.adminUrl = xyz;
ENV.loginUrl = xyz;
but the values might get set to default once you refresh the browser.
I'll assume that the siteid and the regionid can only be obtained from the response to the login endpoint.
Using a constant might not be the best idea here for obvious reasons (i.e. they're constant, and can't be created at the time you want to create them).
Instead, you could do one of a few things - a simple solution that probably works for a lot of use cases would be to create a login service that wraps your API call and then sets a value either in the service or another service that can be injected into wherever you need it.
It might look like this:
angular.module('app')
.service('loginService', function($http) {
var siteId,
regionId;
function login(username, password) {
return $http({
method: 'POST',
url: '<login endpoint here>',
headers: {
"Authorization": "Basic ",
"Content-Type": "application/x-www-form-urlencoded"
}
})
.then(function(result) {
siteId = result.siteId;
regionId = result.regionId;
});
}
);
This makes the values available to you any time you need to make an API call after logging in. However, this isn't great since you will need to inject the loginService into any controller/service that needs it, and that controller/service might not really care about the login service at all.
An improved approach to this could be to have an API service that performs the http gets/sets/puts/posts/whatever and that is accessed by your data access layer. Inside this service, you can set/get the siteid and regionid.
It might look like this:
angular.module('app')
.service('api', function($http) {
var siteId,
regionId;
var defaultHeaders = {
"Authorization": "Basic ",
"Content-Type": "application/x-www-form-urlencoded"
};
function post(url, options) {
return $http({
method: 'POST',
url: url,
headers: options.headers ? options.headers : defaultHeaders
});
}
// Other functions to perform HTTP verbs...
});
angular.module('app')
.service('loginService', function(api) {
function login(username, password) {
api.post('urlHere', options)
.then(function(result) {
api.siteId = result.siteId;
api.regionId = result.siteId;
});
}
});
You can then access the siteid and regionid where you like.
For example:
angular.module('app')
.controller('someService', function(api) {
function doSomethingWithTheApi() {
var url = 'www.google.com/' + api.siteId + '/' + api.regionId + 'whatever-else';
return api.post(url, {});
}
);
Note: the code above isn't complete, but it gives you a very good idea of the approach you could take that is reasonably clean, not too hacky and is easily testable :)
Hope that helps!

AngularJS http call (complete syntax)

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>

AngularJS 1.x How do I use resource to fetch an array of results?

This is what I wrote in my factories.js:
app.factory('CustomerCompany', function($resource){
return $resource('/customer_companies/:id.json', {id: "#_id"}, {
'query':{method: 'GET', isArray:false},
'getByCustomerAccount':{
method: 'GET',
params: {customer_account_id: customer_account_id},
isArray:true,
url:'/customer_companies/get_by_account/:customer_account_id.json'
}
});
});
Because I want to fetch a list of customer_companies that belong to a particular customer_account so I need to supply a customer_account_id.
In my controllers.js,
app.controller('customerAccountEditController', function($scope, CustomerCompany) {
$scope.data = {};
var path = $location.path();
var pathSplit = path.split('/');
$scope.id = pathSplit[pathSplit.length-1];
var customer_account_id = $scope.id;
$scope.list_of_companies = [];
CustomerCompany.getByCustomerAccount({customer_account_id: customer_account_id}, function(data){
console.log(data);
//$scope.list_of_delegates.push(data);
});
});
I get a customer_account_id not defined.
Where did I go wrong?
I think you don't need to define params inside your $resource & then URL will becomes url:'/customer_companies/get_by_account/customer_account_id.json' & while calling a method you need to pass the customer_account_id, from {customer_account_id: customer_account_id} so that it would create an URL with customer_account_id=2 somtehing like that.
Service
'getByCustomerAccount':{
method: 'GET',
//params: {customer_account_id: customer_account_id}, //removed it
isArray:true,
url:'/customer_companies/get_by_account/:customer_account_id'
}
Controller
CustomerCompany.getByCustomerAccount({customer_account_id: customer_account_id + '.json'}, function(data){
console.log(data);
//$scope.list_of_delegates.push(data);
});
This worked for me.
controllers.js
CustomerCompany.getByCustomerAccount({customer_account_id: customer_account_id}, function(data){
console.log(data);
//$scope.list_of_delegates.push(data);
});
services.js
app.factory('CustomerCompany', function($resource){
return $resource('/customer_companies/:id.json', {id: "#_id"}, {
'query':{method: 'GET', isArray:false},
'getByCustomerAccount':{
method: 'GET',
isArray:false,
url:'/customer_accounts/:customer_account_id/customer_companies.json'
}
});
});
What I changed:
on the server side, I decided to use /customer_accounts/:customer_account_id/customer_companies to render the results.
I realized that the data returned is always in object form, so I changed isArray in the $resource to false.
I pass the params like the way the Pankaj Parkar suggested in the controller when I call getByCustomerAccount
params: {customer_account_id: customer_account_id},
The customer_account_id you try to assign here is not defined.
Try params: {customer_account_id: '#customer_account_id'},

How to get request url in an angularjs $http request

I have this request:
$http({
method: 'get',
url: '/api/items/',
params: {a: 1, b: 2, c: 3}
}).success(function (response) {
console.log(response);
}).error(function (err) {
console.log(err);
});
Is there a way, to fetch the url it used to make the request after the request has been made(in the callback or otherwise)?
I would want the output:
http://www.example.org/api/items?a=1&b=2&c=3
Here the same thing is done with jquery.
The success handler gets 4 parameters passed into it:
$http
.get({ url: '/someUrl', params: { q: 3 } })
.success(function(data, status, headers, config) {});
The fourth parameter config has the following properties:
{
method: "GET",
url: {
url: '/someUrl',
params: {
q: 3
}
}
}
You can use window.location.origin to get the base url and build a simple function to concat it all together.
This function should yield the expected response:
var baseUrl = window.location.origin;
var query = [];
Object.keys(config.url.params || {}).forEach(function (key) {
var val = config.url.params[key];
query.push([key, val].join('=')); // maybe url encode
});
var queryStr = query.join('&');
var fullPath = baseUrl + config.url.url + '?' + queryStr;
Unfortunately, this function will only work as long as the parameters are passed in the format described above. If you pass them in a different format, you'll have to modify this function a bit. You can use this as a playground.
Afaik, there is no simpler way. At least a feature request exists.
See the docs of $http for reference
This config parameter of the callback has the url as a property:
// Simple GET request example :
$http.get('/someUrl').
success(function(data, status, headers, config) {
console.log(config.url);
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Based on: https://docs.angularjs.org/api/ng/service/$http
You can use http request Interceptor.
Configure the Interceptor in config function using $httpProvider
Whrein for request Interceptor you can able to see the URL and params that you passed with URL prior to making the request
try just looking at the XHR Request urls in your browser dev tools

Migrating from http to ngResource Angular

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.

Categories