Appending some info to each requset in REST API - angularjs

I have an angular application. From frontend I can set some value. This value is something like config, which can be changed.
It is simple string variable. How to attach this config to each REST request ?
I ask mainly about approach.
Maybe pass it via headers is good idea ?

For angular 1.x, write an Interceptor:
For purposes of global error handling, authentication, or any kind of
synchronous or asynchronous pre-processing of request or
postprocessing of responses, it is desirable to be able to intercept
requests before they are handed to the server and responses before
they are handed over to the application code that initiated these
requests
For angular 2.x / 4.x, RequestOptions should be the key to solve your problem. Set base url for angular 2 http requests
I'm using angular2, my solution is create a Service and inject "Http" dependency, then write two methods "get", "post", these methods add an entry to header before calling "Http", in other component / service, I just inject this Service class, then call its "get" or "post".

Your code should be somewhat like this If your working in angular 1.3 or less
The data should be sent as body data to server
var basecall = Restangular.all('url');
bascall.post($scope.config).then(function(data){
})

Related

Blocking / Initialization service with angular.js

My apps are using many web services on the intranet, and url-s for those depend on the server environment.
My apps are hosted on IIS, which adds an HTTP response header like this: Environment: DEV, so every web app knows in which server environment it is running, and thus which intranet servers it must use to call all the services.
Each of my angular apps uses a service that issues a simple GET against the app's own root just to get any response with the environment name in it, and set configuration accordingly.
Question:
How should an angular app implement such a service that would execute as the very first thing in the application, and make sure that while it is getting that first response, nothing in the app tries to execute an HTTP request against other services, or even try to use any configuration provided by my environment service?
Is there a way to implement such a service in angular that could block every other service / factory in the application till it is done initializing itself?
I have many other services in the app, and none of them really know what to do till my environment service has finished its initialization.
UPDATE
Looking at it from another angle.... is it possible to implement such an interceptor in angular that could do the following?:
execute an HTTP request and block the app's execution till it gets a response
make information from the response available throughout the app as a service/factory/config.
Angular lifecycle could be one solution. Using the angular.config() phase you could peek at the headers of the HTTP service.
Create a factory called 'httpInterceptor'
function httpInterceptors(siteConfig, $q, $injector) {
return {
response: function(data, status, headers) {
siteConfig.setEnvironment(headers['Environment']);
return data;
}
};
)
Then in angular.config()
$httpProvider.interceptors.push('httpInterceptor');
If you truly want to block the other option is to use UI router resolve property to block routes loading until the request has been made https://github.com/angular-ui/ui-router/wiki you can add the resolve method to the root state.
Resolve
You can use resolve to provide your controller with content or data that > is custom to the state. resolve is an optional map of dependencies which > should be injected into the controller.
If any of these dependencies are promises, they will be resolved and converted to a value before the controller is instantiated and the $stateChangeSuccess event is fired.

Angular, Cannot make an an API call probably because of CORS issue

I am trying to make an Angular application consuming Foreign Exchange (forex) market API.
$http({
method: 'GET',
url: 'http://www.apilayer.net/api/live?access_key=[MY ACCESS KEY]'
}).then(function(response){
console.log(response);
})
I keep getting the following error when I look at the browser console.
Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
The weirdest part is that it used to work - I was able to retrieve JSON info from the API call without a problem, but it does not any more.
Is there anyone who can point me to a set of possible causes? Would appreciate it!
If you didn't change anything in your code (say, the path for the api) then it must be one of two thing:
The browser configuration has changed
The api provider has blocked cross domain request, you should contact him, maybe he require callback with jsonp ajax request

Get raw request / response from $http call

I am writing an AngularJs app to test an API we developed. The app uses the $http object to make requests to the API. One of the asks is that after the call it's possible to review the raw HTTP (headers and bodies) Request/Response, similarly to what's available in Fiddler via Raw tabs.
Is it something that $http provides out of the box?
If not, it appears that the only challenge is gaining access to the actual request http headers. It's easy to get the response headers and request/response bodies, but not sure how to get the actual request headers.
Thanks.
If you are using $http service to make your API calls, you can use Interceptors to achieve what you want.
Here is what docs tell us about them:
For purposes of global error handling, authentication, or any kind of synchronous or asynchronous pre-processing of request or postprocessing of responses, it is desirable to be able to intercept requests before they are handed to the server and responses before they are handed over to the application code that initiated these requests. The interceptors leverage the promise APIs to fulfill this need for both synchronous and asynchronous pre-processing.
You can find more in depth explanation in the official docs. For example, here.
Also, there are some questions about interceptors on this site. There are some examples of their usage for displaying loading screen in applications: here, here and, probably, somewhere else.
Hope, this helps.
Yes, AngularJs is wrapped around some JQuery or internally JQlite if JQuery is not present and written in Javascript and it provides some pre-defined services. A typical service looks like the following.
AngularJS docs: tutorial step 5
$ Prefix Naming Convention You can create your own services, and in
fact we will do exactly that in step 11. As a naming convention,
Angular's built-in services, Scope methods and a few other Angular
APIs have a $ prefix in front of the name.
The $ prefix is there to namespace Angular-provided services. To
prevent collisions it's best to avoid naming your services and models
anything that begins with a $.
If you inspect a Scope, you may also notice some properties that begin
with $$. These properties are considered private, and should not be
accessed or modified.
angular.module('myApp')
.factory('myService', function ($http, $injector) {
'use strict';
return $http.get('/endpoint')
.then(function () {
return $injector.get('endpoint');
}
.error(function () {
// handle error
}
};
})
Have a look a the image in AngularJS docs which shows a number of services with the $ prefix. Mostly, wrappers over service. It is reserved. More at FAQ.

CSRF protection for file upload posts

I have an angularJS application in which I use Angular's CSRF protection mechanism for all POST, PUT and other nonsafe web service calls. It works well except for one case: a multipart/form-data POST which uploads a file to the server.
In this case, as I am posting a form and file data directly to the web service, the angular $http service is not involved, and therefore does not append the CSRF header to the request in the way that it does with XHR requests.
I have a couple of questions:
do I need to protect this POST against CSRF (I imagine I do)
can I / how can I get Angular to add the CSRF header to the POST request?
If you uploads a file to the server by means of XHR through jQuery, you can add default header:
$.ajaxSetup({
headers: {
"requestVerificationToken": myToken
}
});
I decided in the end that as the post was made by a form rather than AJAX, the method should have been in a standard MVC controller rather that a WebAPI one. That way I could use the standard MVC Html.AntiForgeryToken helper on the form and the ValidateAntiForgeryToken attribute on the method.

AngularJS: $http.post throws error

I am using Request Bin to post some data. In my controller, I have the following code:
$http.post('http://requestb.in/redacted', fooBar).
success(function(data) {
$scope.fooBarPostedSuccess = true;
}).
error(function(err) {
console.log("Error while posting to Request Bin");
console.log("Error Info : " + err);
});
This is triggered by means on a button on the UI. Now when this gets triggered, the data is not posted to Request Bin and I get this error:
XMLHttpRequest cannot load http://requestb.in/redacted.
Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin.
How do I post data to request bin through an AngularJS controller? Also, what does the above error mean?
EDIT : I wish to add here that I am using Node.js with AngularJS. Is this something to do with Node perhaps?
Ah yes... you are dealing with cross-domain scripting issues. This is not an AngularJS problem, but a browser security limitation and a VERY common friction point.
You cannot POST/PUT/DELETE to another domain (different from the one which is hosting -- localhost in your case) without doing some Cross-Origin Resource Sharing (CORS). You are limited to GET for a cross-domain HTTP request.
You have two options:
See if your API supports any cross-domain capabilities. This might be via CORS or it might be via an overloaded GET API or JSONP.
Proxy requests through your server. Since you are using Node.js, proxying REST through your server is extremely simple... you just need to set up a route handler (like /api/redacted) in your Node.js server and then make a new request to your actual API server with something like Restler (NPM package) and return the result back to your client.
Hope this helps!
EDIT:
Your API supports JSONP (Your API Docs). You should be able to use Angular's JSONP function to access your API's JSONP capabilities. (Angular.js JSONP docs).
Since you want to be able to POST to the service, you will need to use the second approach.
CORS allows both GET and POST
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
http://www.w3.org/TR/cors/
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
Now, that that's out of the way...
I too have found that angular's $http won't let me POST cross domain. I was suspicious about that though because I have jquery ajax calls in other projects that can post cross domain just fine. So, I swapped my $http POST with $.ajax POST and that worked.
// $http({
// url: url,
// method: "POST",
// data: data
// })
// .success(successCallback)
// .error(errorCallback)
// ole reliable
$.ajax({
type : "POST",
url : url,
data : data,
success : successCallback,
error : errorCallback,
cache : false,
dataType : 'json',
})
You can use PutsReq instead of RequestBin. PutsReq supports CORS.

Resources