Default content-type does not replace with new content-type (form-data) in axios in react native app for uploading image - react-native

I want to upload an image with axios in react native. This is my function which call upload image web service api:
function _uploadImgToServer(item) {
const file = {
uri: item.imgData.path,
type: item.imgData.mime,
name: 'ana' + item.imgId
}
const body = new FormData();
body.append('file', file);
console.log('uploadResult saga0', body)
dispatch(uploadImg({ body: JSON.stringify(body)}))
}
this is my axios config:
const instance = axios.create({
baseURL: '****',
responseType: 'json',
timeout: 10000,
headers: {
'WEB_TOKEN': '*****',
'UNIQUE_ID': '*****',
'UNIQUE_KEY': '*****',
Accept: "application/json",
'Content-Type': "multipart/form-data"
},
});
And I call my web service like bellow:
try {
const response = await instance.post(url, data);
return Promise.resolve(response.data);
} catch (error) {
return Promise.reject(error.response);
}
Part of the response I get in last part is:
'My log result' { data: { Code: 3, Message: 'Invalid Entry', Value: null },
status: 200,
statusText: undefined,
headers:
{
...
'content-type': 'application/json; charset=utf-8',
...
},
config:
{ url: 'upload',
method: 'post',
data: '{"_parts":[[{"uri":"file:///data/data/***packageName***/cache/react-native-image-crop-picker/IMG-20201222-WA0017.jpg","type":"image/jpeg","name":"ana_pu8kweg4e"},null]]}',
headers:
{ Accept: 'application/json',
'Content-Type': 'multipart/form-data',
WEB_TOKEN: '*****',
UNIQUE_ID: '****',
UNIQUE_KEY: '****' },
baseURL: '****',
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 10000,
adapter: [Function: xhrAdapter],
responseType: 'json',
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus] },
...
}
As you see in my log result, the content-type in header I have sent is 'multipart/form-data' but server has received 'application/json; charset=utf-8' so I cannot upload my image.
It is worth to mention that if I do not use JSON.stringify, content-type will not be sent at all. I have searched a lot but I could not find any useful response.

I found that my problem was not about "content-type" at all. I had to put image type at the end of the image name.
const file = {
uri: item.imgData.path,
type: item.imgData.mime,
name: 'ana'+item.imgId+'.jpeg'
}
I've just added '.jpeg' at the end of the name. I think it is depended on the backend programmer coding algorithm and It cannot cause problem always.

Related

How i can store an API body response and use it in other test on cypress?

I have this code to store response.body.address_id and use it in the next test but not working.
this is my hole code (two tests) :
`it('Create Address',function(){
return cy.request({
method:'POST',
url: `${Cypress.env('API_URL')}/address/api/v1/addresses`,
headers:{
Authorization : `${Cypress.env('access_token')}`,
"Content-Type": 'application/json',
},
body:{
"address_name": "Home",
"locality_area_street": "16th district",
"city": "DAKAR",
"country": "SENEGAL",
}}
).then((response)=>{
expect(response.status).to.eq(201)
Cypress.env('address_id', response.body.address_id);
})
})
it('Add Address',function(){
cy.request({
method:'PUT',
url: 'https://api/v1/cart/address',
headers:{
Authorization : `Bearer ${Cypress.env('access_token')}`,
"Content-Type": 'application/json',
},
body:{
"addressType": "BILLING",
"id": `${Cypress.env('address_id')}`
}}
).then((response)=>{
cy.log(Cypress.env('address_id'));
expect(response.status).to.eq(200)
})
})
})`
Can somme one help me to find a solution ?
You probably shouldn't use the Cypress.env for this,
Try this:
it("Create Address", function () {
return cy
.request({
method: "POST",
url: `${Cypress.env("API_URL")}/address/api/v1/addresses`,
headers: {
Authorization: `${Cypress.env("access_token")}`,
"Content-Type": "application/json",
},
body: {
address_name: "Home",
locality_area_street: "16th district",
city: "DAKAR",
country: "SENEGAL",
},
})
.then((response) => {
expect(response.status).to.eq(201);
Cypress.env("address_id", response.body.address_id);
this.address_id = response.body.address_id;
});
});
it("Add Address", function () {
cy.request({
method: "PUT",
url: "https://api/v1/cart/address",
headers: {
Authorization: `Bearer ${Cypress.env("access_token")}`,
"Content-Type": "application/json",
},
body: {
addressType: "BILLING",
id: this.address_id,
},
}).then((response) => {
cy.log(this.address_id);
expect(response.status).to.eq(200);
});
});

Simple axios call using wait and async works but when i put in in redux-thunk. it start giving errors in react native

import axios from 'axios'
export const loadData = (basicAuth, URL) => {
return (dispatch, getState) => {
dispatch({ type: 'LOGIN_START' })
axios.post(
URL,
null,
{ params: { 'email': 'zack', 'password': 'zack' } },
{
headers: {
"Content-Type":
"application/x-www-form-urlencoded; charset=UTF-8",
'Accept': "*/*",
'authorization': basicAuth,
"Access-Control-Allow-Credentials": true,
},
}
).then(function (response) {
dispatch({ type: 'LOGIN_SUCCESS', payload: response })
}).catch(function (error) {
dispatch({ type: 'LOGIN_FAILURE', payload: error })
})
}
}
When call this request in the main thread using wait and async it works but when i call it using this reduc-thunk it start giving errors.
{"DONE": 4, "HEADERS_RECEIVED": 2, "LOADING": 3, "OPENED": 1, "UNSENT": 0, "_aborted": false,
"_cachedResponse": undefined, "_hasError": true, "_headers": {"accept": "application/json,
text/plain, /", "content-type": "application/x-www-form-urlencoded"}, "_incrementalEvents":
false, "_lowerCaseResponseHeaders": {}, "_method": "POST", "_perfKey":
"network_XMLHttpRequest_Basic emFjazp6YWNr?email=zack&password=zack", "_performanceLogger":
{"_closed": false, "_extras": {}, "_pointExtras": {}, "_points": {"initializeCore_end":
1659600973109, "initializeCore_start": 1659600972966}, "_timespans":
{"network_XMLHttpRequest_Basic emFjazp6YWNr?email=zack&password=zack": [Object],
"network_XMLHttpRequest_http://10.0.2.2:8081/logs": [Object]}}, "_requestId": null,
"_response": "Expected URL scheme 'http' or 'https' but no colon was found", "_responseType":
"", "_sent": true, "_subscriptions": [], "_timedOut": false, "_trackingName": "unknown",
"_url": "Basic emFjazp6YWNr?email=zack&password=zack", "data": undefined, "readyState": 4,
"responseHeaders": undefined, "status": 0, "timeout": 0, "upload": {}, "withCredentials":
true}

Error: Request failed with status code 400 in react-native with axios

axios({
method: 'POST',
url: `http://${base_url}/token`,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
data: {
"Username": "admin#diginepal.com",
"Password": "password#123456",
"grant_type": "password"
}
})
.then(res => {
console.log(res)
})
.catch(err => {
console.log(err)
})
I'm getting err: request failed with status code 400. What am I doing wrong here?
data: qs.stringify({
"Username": "admin#diginepal.com",
"Password": "password#123456",
"grant_type": "password"
})
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
using qs and changing the headers solved my problem.
Good that you managed to solve, for future reference, if you have a 400 Bad Request error, i found really useful to print the error.response.data for more meaningful error messages.
axios.post('/').then(response => {
console.log(response.data);
}).catch(error => {
console.log(error.response.data);
});

error SyntaxError: Unexpected token < in JSON at position 0 with paramsquery

Using an api of live server but while testing in api in postman it uses query param but how to use in react native to call the api
let response = await fetch(URI + '/staging-somewebsite.com/index.php?route=webservices/api&method=appRegisterUser', {
method: 'POST',
headers: {
'Accept': 'application/json',
},
Params:{
'route': 'webservices/api',
'method': 'appRegisterUser',
},
body: JSON.stringify({
firstname: this.state.firstname,
lastname: this.state.lastname,
email: this.state.email,
mobile_number: this.state.mobile_number,
password: this.state.password,
})
});

upload expo camera roll image to server

I'm using expo camera to take a picture. The output I get is a file in format file:///data/user/0/host.exp.exponent/..../Camera/1075d7ef-f88b-4252-ad64-e73238599e94.jpg
I send this file path to the following action and try to upload it to
export const uploadUserPhoto = (localUri,uid) => async dispatch => {
let formData = new FormData();
formData.append('avatar', { uri: localUri, fileName: uid});
let res = await fetch(`${API_URL}api/uploadPhoto`, {
method: 'POST',
body: formData,
header: {
'content-type': 'multipart/form-data',
},
});
Afterward, I get [Unhandled promise rejection: TypeError: Network request failed] and nothing arrives to server. I tried using some string to send in the body and the fetch worked, so I guess it has something to do with my formData configuration.
The formData is:
{
"_parts": Array [
Array [
"avatar",
Object {
"fileName": "6eAntcmoEsdBeSD2zfka9Nx9UHJ3",
"type": "jpg",
"uri": "file:///data/us....2e6e3e8d3223.jpg",
},
],
],
}
How I use postman to test my sails controller
Sails controller function:
uploadPhoto: function (req, res) {
req.file('avatar').upload({
adapter: require('skipper-s3'),
key: 'XXXX',
secret: 'XXX',
bucket: 'XXX',
saveAs: req.param('fileName') + '.png',
}, function (err, filesUploaded) {
....
});
});
}
Problem was that I didn't specify the filename.
Just did this and it worked!!! :)
data.append('filename', 'avatar');
data.append('fileName', uid);
data.append('avatar', {
uri: photo.uri,
name: 'selfie.jpg',
type: 'image/jpg'
});
const config = {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
body: data
};
fetch(`${API_URL}api/uploadPhoto`, config).then(responseData => {
console.log(responseData);
}).catch(err => { console.log(err); });
just add these params in photo this worked for me
data.append('avatar', {
uri: photo.uri,
name: 'selfie.jpg',
type: 'image/jpg'
});