I am trying to use an API with HTTP POST request and It seems to work but when I get the response it's empty.
The API should receive base64
encoded image inside the body.
The argument imageToRead
ing from a promise returned with the Camera
ponent from react-native-camera
. I'm not sure maybe the problem there?
This is the content:
imageToRead = "/var/mobile/Containers/Data/Application/01B81FC9-B171-11GB-9B48-9D06F89B175A/Documents/3A997ACD-D63C-41BD-9041-FDB834A0672A.jpg"
This API can also receive formData
files and that how I tested it with and it went great in Node environment. But because my application is a native iOS application, I had to use other tools (like React Native) and can not use the same ones.
Code to test the API in Node:
var formData = {image: fs.createReadStream('/Users/Desktop/APITest/img/testOCR8.jpg')};
request.post({
url:'${url}',
formData: formData},
(err, httpResponse, body) => {
if (err) {
return console.error('upload failed:', err);
}
console.log(body);
});
You can see I use fs.createReadStream
from the fs
module to create stream of the file and then use it inside the request body.
I couldn't replicate the same thing using React Native (if you have a solution so I could do it with React Native it would be even better!!)
So I tried deferent way and tried to encode the file I got from the camera.capture()
method that e with react-native-camera
to base64
and to place it inside the body but the response I got is empty without any errors, just an empty object.
Code with React Native:
recognise = (imageToRead) => {
RNFetchBlob.fs.readFile(imageToRead , 'base64')
.then((data) => {
fetch('${url}',{
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: data // the body contain the encoded image
})
.then((res) => { // promise returned with the response from the API
console.log(`i am the base64Image: ${data}`)
console.log('i am response', res)
})
.catch((errInFetch) => { // catch any error in the API
console.log('i am error:', errInFetch)
})
})
.catch((err) => {
console.log(err);
})
}
Response:
{ type: 'default',
status: 200,
ok: true,
statusText: undefined,
headers:
{ map:
{ server: [ 'nginx/1.10.3' ],
'content-type': [ 'application/json; charset="utf-8"' ],
'access-control-allow-origin': [ '*' ],
date: [ 'Thu, 10 May 2018 10:17:48 GMT' ],
'access-control-allow-headers': [ 'x-requested-with' ],
'content-encoding': [ 'gzip' ],
'content-length': [ '237' ],
connection: [ 'keep-alive' ] } },
url: ';country=eu',
_bodyInit:
{ _data:
{ size: 371,
blobId: '5080ACA4-5D13-469C-B755-96B06A161FC6',
type: 'application/json',
offset: 0,
name: 'recognize_bytes' } },
_bodyBlob:
{ _data:
{ size: 371,
blobId: '5080ACA4-5D13-469C-B755-96B06A161FC6',
type: 'application/json',
offset: 0,
name: 'recognize_bytes' } } }
I hope someone can help with this. I have struggle with it for so long time.
I am trying to use an API with HTTP POST request and It seems to work but when I get the response it's empty.
The API should receive base64
encoded image inside the body.
The argument imageToRead
ing from a promise returned with the Camera
ponent from react-native-camera
. I'm not sure maybe the problem there?
This is the content:
imageToRead = "/var/mobile/Containers/Data/Application/01B81FC9-B171-11GB-9B48-9D06F89B175A/Documents/3A997ACD-D63C-41BD-9041-FDB834A0672A.jpg"
This API can also receive formData
files and that how I tested it with and it went great in Node environment. But because my application is a native iOS application, I had to use other tools (like React Native) and can not use the same ones.
Code to test the API in Node:
var formData = {image: fs.createReadStream('/Users/Desktop/APITest/img/testOCR8.jpg')};
request.post({
url:'${url}',
formData: formData},
(err, httpResponse, body) => {
if (err) {
return console.error('upload failed:', err);
}
console.log(body);
});
You can see I use fs.createReadStream
from the fs
module to create stream of the file and then use it inside the request body.
I couldn't replicate the same thing using React Native (if you have a solution so I could do it with React Native it would be even better!!)
So I tried deferent way and tried to encode the file I got from the camera.capture()
method that e with react-native-camera
to base64
and to place it inside the body but the response I got is empty without any errors, just an empty object.
Code with React Native:
recognise = (imageToRead) => {
RNFetchBlob.fs.readFile(imageToRead , 'base64')
.then((data) => {
fetch('${url}',{
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: data // the body contain the encoded image
})
.then((res) => { // promise returned with the response from the API
console.log(`i am the base64Image: ${data}`)
console.log('i am response', res)
})
.catch((errInFetch) => { // catch any error in the API
console.log('i am error:', errInFetch)
})
})
.catch((err) => {
console.log(err);
})
}
Response:
{ type: 'default',
status: 200,
ok: true,
statusText: undefined,
headers:
{ map:
{ server: [ 'nginx/1.10.3' ],
'content-type': [ 'application/json; charset="utf-8"' ],
'access-control-allow-origin': [ '*' ],
date: [ 'Thu, 10 May 2018 10:17:48 GMT' ],
'access-control-allow-headers': [ 'x-requested-with' ],
'content-encoding': [ 'gzip' ],
'content-length': [ '237' ],
connection: [ 'keep-alive' ] } },
url: 'https://api.openalpr./v2/recognize_bytes?secret_key=key&country=eu',
_bodyInit:
{ _data:
{ size: 371,
blobId: '5080ACA4-5D13-469C-B755-96B06A161FC6',
type: 'application/json',
offset: 0,
name: 'recognize_bytes' } },
_bodyBlob:
{ _data:
{ size: 371,
blobId: '5080ACA4-5D13-469C-B755-96B06A161FC6',
type: 'application/json',
offset: 0,
name: 'recognize_bytes' } } }
I hope someone can help with this. I have struggle with it for so long time.
Share Improve this question edited May 10, 2018 at 18:04 obiwankenoobi asked May 10, 2018 at 13:32 obiwankenoobiobiwankenoobi 1,5825 gold badges23 silver badges37 bronze badges3 Answers
Reset to default 2fetch
returns a promise
containing the response (a Response object). then you again need to parse that using response.json()
which returns promise resolving JSON
.
fetch(url, {
body: JSON.stringify(data),
cache: 'no-cache',
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json'
},
method: 'POST', // *GET, POST, PUT, DELETE, etc.
})
.then(response => response.json())
for more info : read
.then((res) => {
console.log(`i am the base64Image: ${data}`)
console.log('i am response', res)
return res.json();
})
.then(res => {
console.log(res);
})
.catch((errInFetch) => { // catch any error in the API
console.log('i am error:', errInFetch)
})
Fetch response body returns a Promise that will be resolved by json().
So you can get your real data from res.json()
.
The 200 status is for a success get http request. Your API should return status 201 for post with a message instead of 200, for example:
res.status(201).send(data);
full example
also, you can look at the status 201 description