Axios multipart request by PUT method - reactjs

I want to make a put multipart request but it is calling POST even though I tried setting the method to "PUT"
config = {..., method:"PUT"}
axios.request("/getAll", formData, config)
Also, I have a confusion regarding two methods of Axios
Axios.request() and Axios.get()
What is the difference when we call request with method set to GET in config while calling axios.request() and directly calling axios.get()?
Thanks in advance

axios.request takes only 1 argument: config. So you should use:
axios.request({ url: '/getAll', method: 'put', data: formData })
axios.get, axios.put etc are aliases for requests, so you just write less code, because you don't need to specify request's type
axios.put('/getAll', formData)
As a summary, there is no difference between:
axios.request({ url: '/getAll', method: 'get' })
and
axios.get('/getAll')
The second option is just easier and cleaner.

Related

Axios in React app. Posting image with form data sends request with empty body

I'm trying to send image file to my backend API. Last works fine with Postman. The problem is not with image, I'm not able to send any request with axios and form data, no meter I append image or not.
Everything works fine with fetch. It took time to understand, that fetch does not need any content type, and last generates automatically as multipart/form-data with right boundary.
As written axios should do same as fetch, but it does not generate or change its content-type. Passing header 'content-type' : 'multipart/form-data does not do the trick of course. When I do not set content type it just use application/json. I was not able to find anything like that in documentation. Everywhere its says, that axios should create content type header automatically.
My axios version is 0.18.0.
Here is code, it can't be more simple =)
axios
.post(url, payload)
#######UPDATE#######
It turned out the problem was with axios interceptor. If you don't use interceptors you won't get this problem. So when I created new instance and deleted all headers no interceptors where called that's why my code worked. But let me bring more details to help others avoid this pain. Interceptor has transformRequest function where this part of code exists
if (utils.isObject(data)) {
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
return JSON.stringify(data);
}
where setContentTypeIfUnset function is
function setContentTypeIfUnset(headers, value) {
if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
headers['Content-Type'] = value;
}
}
So if your object has undefined headers you will also pass this situation. But in my case even after deleting all headers I must pass some header to my application. And on setting it interceptor calls that transfromRequest function which adds that header to my formdata request.
I hope in future releases axios will fix this issue.
#######OLD ANSWER#######
As I guessed, somehow axios in my project set its default value for header content type and even setting it as 'content-type' : undefined did not overwrite that value.
Here is solution
let axiosInstance = axios.create();
delete axiosInstance.defaults.headers;
Then use that instance.
Spent whole day to find this solution.
const formData = new FormData();
formData.append('image', image); // your image file
formData.append('description','this is optional description');
Axios.post(`your url`, {body:formData}, {
headers: {
'content-type': 'multipart/form-data'
}
})
Can you please try this code once ?
You can try like this:
axios({
method: 'post',
url: 'myurl',
data: bodyFormData,
headers: {'Content-Type': 'multipart/form-data' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});

$http data vs params when making POST request

Preface: I am using AngularJS 1.5.9.
When writing my service, this code works when posting to the server:
var request = {
url: '/connect/token',
method: 'POST',
data: $httpParamSerializer(params),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
$http(request).then(function(response) {});
However, it seems counterintuitive to use data when $http has the usage argument params, with the following definition as per AngularJS's documentation:
params – {Object.} – Map of strings or objects which
will be serialized with the paramSerializer and appended as GET
parameters.
As you can see, the documentation specifies that this argument is meant to be used only for GET requests. I confirmed as much when I attempted to use the params argument with my POST request:
var request = {
url: '/connect/token',
method: 'POST',
params: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
$http(request).then(function(response) {});
When you submit the POST request in this way, you get the following response from the server:
{
"error":"invalid_request",
"error_description":"A malformed token request has been received: the mandatory 'Content-Type' header was missing from the POST request."
}
In other words, if I don't use the data argument and invoke the param serializer service on the params I want to pass in, my custom service won't set the Content-Type header on my request, I've confirmed this in the network tab of the web inspector.
TLDR; Why do I have to use the data argument and serialize the params instead of just using the params argument directly? And why is the content type I specify ignored when I do use the params argument?
Use params option for GET requests.
With params option you can set URL query string parameters like baseurl.com?myParam=something

set header angular http service put

Having difficulty with a temporary work around but the intent was to add to a http put request a header with string value, 'username' : 'flastname'. Within the service that invokes the put call, just before the $http.put call, the username header is to be set.
$http.defaults.headers.post.username = 'flastname';
$http.put('http://localhost:8080/xxxxx-integration/api/claims',claim);
Server side, retrieving a http header 'username' always results in null and in the even stranger behavior than expected category is random numbers of http put calls are generated. Thought I followed the documentation at:
https://docs.angularjs.org/api/ng/service/$http
but maybe read it wrong.
Have you tried the shortcut method? According to the docs, you should be able to do it like so:
put(url, data, [config]);
$http.put('http://localhost:8080/xxxxx-integration/api/claims',claim , {
headers: {'username': 'flastname'}
});
var req = {
method: 'PUT',
url: 'http://localhost:8080/xxxxx-integration/api/claims',
headers: {
'username': 'flastname'
},
data: { test: 'test' } // json for data
}
now just put the req varaible inside $http :)
$http(req).then(function()...)

send request without adding header in angular js

i'm trying to sending request to third party service. for that i need to delete default header 'x-access-token'. For that did like below
$http({
url: 'http://ip-api.com/json',
method: 'GET',
transformRequest: function(data, headersGetter) {
var headers = headersGetter();
delete headers['x-access-token'];
return headers;
}
}).then(function(res){
console.log(res);
},function(error){
console.log(error);
});
By following this link .
But i'm getting this error
TypeError: Cannot convert object to primitive value
at angular.js:10514
at sendReq (angular.js:10333)
at $get.serverRequest (angular.js:10045)
at processQueue (angular.js:14567)
at angular.js:14583
at Scope.$get.Scope.$eval (angular.js:15846)
at Scope.$get.Scope.$digest (angular.js:15657)
at Scope.$get.Scope.$apply (angular.js:15951)
at done (angular.js:10364)
at completeRequest (angular.js:10536)
"transformRequest" does not work the same way to remove headers for individual requests past angularjs 1.4 release .From the documentation its clear that we should be using "headers" instead
eg:
$http({method: 'GET',
url: "url",
headers: {
'header-name': undefined
}
}).success(function(data){console.log(data)});
The $http service config object allows you to override the http header send for a specific request. See config property headers.
To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis, Use the headers property, setting the desired header to undefined.
NOTE: Set the desire header/headers to undefined like this, then it will not affect the global settings.
See example:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': undefined
},
data: { test: 'test' }
}
$http(req).then(function(){...}, function(){...});
See more documentation.
This can take a list of headers or a function that return a list of headers. So for the non auth header request make a copy of the default headers remove the header you don't require and then make the request.
Hope this help well.

AngularJS $http POST request different results with then and success

Something is driving me nuts; maybe someone can help me out with the following? :
I am using AngularJS 1.2.26 (have to because IE8 needs to be supported)
I have to invoke some backend services that were initially build for a backbone frontend. I managed to do that in the following way:
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: this._transformRequest,
data: formData
})
.success(function (data) {
// bla bla not relevant
}).error(function (error) {
// bla bla not relevant
});
Now i try to work with the then function as i find that more consequent, so i change the code into:
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: this._transformRequest,
data: formData
}).then(
function (response) {
// not relevant
}, function (error) {
// not relevant
});
According to me, in theory this should have the same result as the initial implementation, however to my surprise the request now fails on the server. While debugging I noticed that the result of the transform request function delivers a very different result in both scenario's in the request that is handled with success and error the result of transform request is as follows:
com.bank.token.session=XXXXX&model=%7B%22relatieRol%22%3A%22AANVRAGER%22%2C%22evaUitgevoerdDat%22%3Anull%2C%22sfhUitgevoerdDat%22%3Anull%2C%22bkrUitgevoerdDat%22%3Anull%2C%22bkrBekendCd%22%3A%22GOED_BEKEND%22%7D
When i use the 'then' function as the way to handle the result the transformRequest function returns the following (wrong) result:
com.bank.token.session=XXXXXXXXXXX&model=%7B%22data%22%3A%7B%22relatieRol%22%3A%22AANVRAGER%22%2C%22evaUitgevoerdDat%22%3Anull%2C%22sfhUitgevoerdDat%22%3Anull%2C%22bkrUitgevoerdDat%22%3Anull%7D%2C%22status%22%3A200%2C%22config%22%3A%7B%22method%22%3A%22POST%22%2C%22transformResponse%22%3A%5Bnull%5D%2C%22url%22%3A%22http%3A%2F%2Flocalhost%2Femployee%2Findex.html%2Ffoo-web%2Fxchannel-foo-secure-portlet%2F1598792178%2Fver%3D2.0%2Fresource%2Fid%3Dfoo-fetch-%2Frparam%3Dportal%3DfooPortal.wsp%22%2C%22headers%22%3A%7B%22Content-Type%22%3A%22application%2Fx-www-form-urlencoded%22%2C%22Accept%22%3A%22application%2Fjson%2C%20text%2Fplain%2C%20*%2F*%22%7D%2C%22data%22%3A%7B%22com.bank.token.session%22%3A%22XXXXXXXXXX%22%2C%22model%22%3A%22%7B%5C%22relatieRol%5C%22%3A%5C%22AANVRAGER%5C%22%7D%22%7D%7D%2C%22statusText%22%3A%22OK%22%2C%22bkrBekendCd%22%3A%22GOED_BEKEND%22%7D
This really surprises me; how can the handler on the $http service influence the way the request is handled? I would like to use 'then' for handling my $http POST; but it seems not to work. Anybody knows why? Many thanks in advance!
my transformRequest function looks like this:
_transformRequest: function (obj) {
var str = [];
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
}
console.log('transform: ', str.join("&"));
return str.join("&");
}
success and error unpack the data property of the response for you (as well as route to the pretty names). So, if you change to then you need to manually address the data property of the response in order to get the same information:
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: this._transformRequest,
data: formData
}).then(
function (response) {
var data = response.data;
// not relevant
}, function (error) {
var data = error.data;
// not relevant
});
Here is the relevant part in the $http documentation:
Returns a promise object with the standard then method and two http
specific methods: success and error. The then method takes two
arguments a success and an error callback which will be called with a
response object. The success and error methods take a single argument
- a function that will be called when the request succeeds or fails respectively. The arguments passed into these functions are
destructured representation of the response object passed into the
then method. The response object has these properties:
data – {string|Object} – The response body transformed with the transform functions.
status – {number} – HTTP status code of the response.
headers – {function([headerName])} - Header getter function.
config – {Object} – The configuration object that was used to generate the request.
statusText – {string} – HTTP status text of the response.
The $http legacy promise methods success and error have been deprecated. Use the standard then method instead.1

Resources