I am working with antd framework and I have to use upload API. This is the signature:
action: Uploading URL : string|(file) => Promise
I am invoking the API in this way trying to return a Promise:
<Upload {...propsUpload}>
<Button> <Icon type="upload" />Upload</Button>
</Upload>
with propsUpload that refers to function uploadMedia
const propsUpload = {
action: this.uploadMedia,
listType: 'picture',
defaultFileList: [],
className: 'upload-list-inline',
};
and this is the function uploadMedia
uploadMedia = (file) => {
let formData = new FormData();
formData.append('file', file);
formData.append('uuid', this.generateuuid());
formData.append('domain', 'POST');
formData.append('filename', file.name );
return fetch(process.env.REACT_APP_API_URL +
'/v100/media/upload', {
method: 'POST',
credentials: 'include',
headers: {
Accept: 'application/json'
},
body: formData
})
.then(response => response.json())
.then(data => data.data)
.catch(error => {
console.log('Error fetching profile ' + error)
})
}
The file is uploaded to server correctly. But after the call to API, antd try to do another call that fails, maybe because I am not returning the correct value from function.
As result the thumbnail is displayed with red border and and error is shownd. In the image below there are both (the call that fails and image with red border)
What type of object I have to return in function uploadMedia to use api correctly?
Thanks
I am working with antd framework and I have to use upload API. This is the signature:
action: Uploading URL : string|(file) => Promise
I am invoking the API in this way trying to return a Promise:
<Upload {...propsUpload}>
<Button> <Icon type="upload" />Upload</Button>
</Upload>
with propsUpload that refers to function uploadMedia
const propsUpload = {
action: this.uploadMedia,
listType: 'picture',
defaultFileList: [],
className: 'upload-list-inline',
};
and this is the function uploadMedia
uploadMedia = (file) => {
let formData = new FormData();
formData.append('file', file);
formData.append('uuid', this.generateuuid());
formData.append('domain', 'POST');
formData.append('filename', file.name );
return fetch(process.env.REACT_APP_API_URL +
'/v100/media/upload', {
method: 'POST',
credentials: 'include',
headers: {
Accept: 'application/json'
},
body: formData
})
.then(response => response.json())
.then(data => data.data)
.catch(error => {
console.log('Error fetching profile ' + error)
})
}
The file is uploaded to server correctly. But after the call to API, antd try to do another call that fails, maybe because I am not returning the correct value from function.
As result the thumbnail is displayed with red border and and error is shownd. In the image below there are both (the call that fails and image with red border)
What type of object I have to return in function uploadMedia to use api correctly?
Thanks
Share Improve this question edited Mar 26, 2019 at 23:40 fciri asked Mar 26, 2019 at 23:15 fcirifciri 3077 silver badges20 bronze badges 4-
what is
process.env.REACT_APP_API_URL
? – AlexZvl Commented Mar 26, 2019 at 23:21 - It's a variable containg the URL of server. Please note that the call to server works fine and image is uploaded on server. – fciri Commented Mar 26, 2019 at 23:27
-
I just saw the url in the console which for some reason contains
[object20object]
. I Guess it should not be there – AlexZvl Commented Mar 26, 2019 at 23:32 - @AlexandrZavalii thanks for response. The problem seems that fetch return a json object instead of a promise and it's treated as url. – fciri Commented Mar 26, 2019 at 23:37
4 Answers
Reset to default 3For those who are not clear how to actually implement it (and it is unclear in docs):
Just implement a customRequest function in the props that accepts two callbacks, which are onError and onSuccess, and other data such as file and filename.
Like this
const props = {
customRequest: (ponentsData) => {
let formData = new FormData();
formData.append('file', ponentsData.file);
formData.append('uuid', this.generateuuid());
formData.append('domain', 'POST');
formData.append('filename', ponentsData.file.name );
fetch(process.env.REACT_APP_API_URL + '/v100/media/upload', {
method: 'POST',
credentials: 'include',
headers: {
Accept: 'application/json'
},
body: formData
})
.then(response => response.json())
.then(data => data.data)
.then(data=> ponentsData.onSuccess())
.catch(error => {
console.log('Error fetching profile ' + error)
ponentsData.onError("Error uploading image")
})
}
}
And let Upload ponent receive the props.
const App = () => {
return <Upload {...props} />
}
I haven't used antd but looking at the docs of Uplaod
ponent I think you're using it wrong. Look at the examples there and see the code, action
expects either a URL or a Promise that will return this URl. And Upload
in this case will make request itself, so you don't need to do fetch
. And your promise returns the data
(object) so the Upload sends the request to [object Object]
(which is what's returned by .toString()
when applied to an object in JS)
EDIT
Try to check all examples in docs, I can see that there is an example when you want to manually upload the file (if you really need it)
For anyone looking to access the response object after calling the API. There are two ways you can get access to the response.
- Implement a custom API request mentioned as in other answers for this question.
- Use the onChange method provided by AntD (Which is the easier than utilizing the custom request)
I will explain the second approach below using a code block.
const fileUploadProps = {
name: "file",
action: config.remote + "api/file",
method: "POST",
showUploadList: false,
headers: {
authorization: "authorization-text",
contentType: "multipart/form-data"
},
onChange(info) {
if (info.file.status === "done") {
const { response } = info.file;
updateProfile(response.payload.file);
} else if (info.file.status === "error") {
message.error("Error uploading the file");
props.endLoad();
}
},
beforeUpload(file) {
const isJpgOrPng = file.type === "image/jpeg" || file.type === "image/png";
if (!isJpgOrPng) {
message.error("You can only upload JPG/PNG file!");
}
const isLt2M = file.size / 1024 / 1024 < 2;
const isGT20K = file.size / 1024 > 20;
if (!isLt2M) {
message.error("Image must smaller than 2MB!");
}
if (!isGT20K) {
message.error("Image must larger than 20KB!");
}
if (isJpgOrPng && isLt2M && isGT20K) {
props.startLoad();
return true;
} else {
return false;
}
}
};
In Render function I have the AntD upload ponent
<Upload {...fileUploadProps}>
<Button icon={<CameraFilled style={{ fontSize: "30px" }} />}></Button>
</Upload>
You can notice how I got the access to the response object inside onChange function. Once the upload is plete it will call the onChange function having response object inside the info object.
So from there you can get access to your data object easily and call the next method.
I solved using api customRequest in this way:
uploadMedia = (ponentsData) => {
let formData = new FormData();
formData.append('file', ponentsData.file);
formData.append('uuid', this.generateuuid());
formData.append('domain', 'POST');
formData.append('filename', ponentsData.file.name );
fetch(process.env.REACT_APP_API_URL + '/v100/media/upload', {
method: 'POST',
credentials: 'include',
headers: {
Accept: 'application/json'
},
body: formData
})
.then(response => response.json())
.then(data => data.data)
.then(data=> ponentsData.onSuccess())
.catch(error => {
console.log('Error fetching profile ' + error)
ponentsData.onError("Error uploading image")
})
}