Hi,
The KendoReact Upload component seems to only cater for sending files to dedicated server handlers. Is there any way to convert attached files to a byte array rather than posting to a server endpoint?
Kind regards,
David
7 Answers, 1 is accepted
Hello, David,
The saveUrl can accept a function instead of a direct link.
This will allow the developer to get access to the files and use them as required, including transferring them to byte arrays:
https://www.telerik.com/kendo-react-ui/components/upload/api/UploadProps/#toc-saveurl
We have an example in this GitHub item as well:
https://github.com/telerik/kendo-react/issues/193
Please have in mind that the upload will provide only the file, any further conversion or modifications has to be done programmatically.
I hope this is helpful.
Regards,
Stefan
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Thanks Stefan,
Are there any plans to add automatic transferral to byte arrays, or chunked upload of large files?
Kind regards,
David
Hello, David,
Any new features are based on the community requests in our portal.
If you wish a method that will do this conversion, please log a feature request for it and we will plan it accordingly:
https://feedback.telerik.com/kendo-react-ui
Regards,
Stefan
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Hi Stefan,
As discussed I am attempting to use the Upload component to transfer a single file to a byte array. I was hoping that you could confirm that the implementation below is valid, specifically:
- is it possible / necessary to call FileReader.abort() from the onCancel?
- is it necessary to reject the uid on FileReader.abort() given that a cancel always seems to result in a subsequent Remove?
- is there a list of the possible UploadFileInfo.validationErrors anywhere? It would be nice to present some sort of error in the Upload component on FileReader.abort or error (see attached for a simulated error part way through the upload process, the progress bar is red and the 'Done' text has a warning icon but there is no validation message to indicate why)
import React, { useEffect, useState } from
"react"
;
import { Upload, UploadFileInfo, UploadFileStatus } from
"@progress/kendo-react-upload"
;
interface IKendoFileUpload {
files: UploadFileInfo[] | undefined;
content: string | undefined;
}
export
function
KendoSingleFileUpload(props: {
selectedFile: UploadFileInfo | undefined;
content: string | undefined;
allowedExtensions?: string[] | undefined;
minFileSize?: number | undefined;
maxFileSize?: number | undefined;
onFileValidlySelected: (selectedFile: UploadFileInfo | undefined, content: string | undefined) => void;
}) {
const [files, setFiles] = useState<UploadFileInfo[] | undefined>(
new
Array<UploadFileInfo>());
const [content, setContent] = useState<string>(
""
);
useEffect(() => {
setFiles(props.selectedFile ? [props.selectedFile] :
new
Array<UploadFileInfo>());
}, [props.selectedFile]);
useEffect(() => {
setContent(props.content ??
""
);
}, [props.content]);
function
onAdd(event: any) {
setFiles(event.newState);
}
function
onCancel(event: any) {
// abort reader?
}
function
onProgress(event: any) {
setFiles(event.newState);
}
function
onRemove(event: any) {
setFiles(event.newState);
}
function
onStatusChange(event: any) {
setFiles(event.newState);
}
function
onSaveRequest(
files: UploadFileInfo[],
options: { formData: FormData; requestOptions: any },
onProgress: (uid: string, event: ProgressEvent<EventTarget>) => void
): Promise<{ uid: string }> {
const currentFile = files[0] as UploadFileInfo;
const uid = currentFile.uid;
const saveRequestPromise =
new
Promise<{ uid: string }>(async (resolve, reject) => {
if
(currentFile.validationErrors && currentFile.validationErrors.length > 0) {
reject({ uid: uid });
}
else
{
const reader =
new
FileReader();
reader.onload = () => {
if
(reader.result &&
typeof
reader.result ===
"string"
) {
// stripping the data-url declaration as per https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
const base64Result = reader.result.split(
","
)[1];
setContent(base64Result);
resolve({ uid: uid });
}
reject({ uid: uid });
};
reader.onabort = () => {
// reject({ uid: uid }); ?
};
reader.onerror = () => {
reject({ uid: uid });
};
reader.onprogress = (data) => {
onProgress(uid, data);
};
reader.readAsDataURL(currentFile.getRawFile!());
}
});
return
saveRequestPromise;
}
function
onRemoveRequest(files: UploadFileInfo[], options: { formData: FormData; requestOptions: any }): Promise<{ uid: string }> {
const currentFile = files[0] as UploadFileInfo;
const uid = currentFile.uid;
const removeRequestPromise =
new
Promise<{ uid: string }>((resolve) => {
setContent(
""
);
resolve({ uid: uid });
});
return
removeRequestPromise;
}
return
(
<Upload
autoUpload={
false
}
batch={
false
}
files={files}
multiple={
false
}
onAdd={onAdd}
onCancel={onCancel}
onProgress={onProgress}
onRemove={onRemove}
onStatusChange={onStatusChange}
withCredentials={
false
}
removeUrl={onRemoveRequest}
saveUrl={onSaveRequest}
restrictions={{ allowedExtensions: props.allowedExtensions, minFileSize: props.minFileSize, maxFileSize: props.maxFileSize }}
/>
);
}
Hello, David,
Thank you for the provided code.
Regarding the questions:
1) is it possible / necessary to call FileReader.abort() from the onCancel? -
- Possible: it will be possible if the нew FileReader() is created on a top-level, so each function has access to it.
- Necessary: This will depend on the application and its requirements, if the read operation has to stop then the method can be called.
2) is it necessary to reject the uid on FileReader.abort() given that a cancel always seems to result in a subsequent Remove? - If we know that the process will stop it is better to reject it. Is there any issue caused by the reject that lead to this question?
3) is there a list of the possible UploadFileInfo.validationErrors anywhere? - This property expects one of the message keys listed here:
https://www.telerik.com/kendo-react-ui/components/upload/globalization/#toc-messages (The messages can be customized as well.)
I made an example showcasing this:
https://stackblitz.com/edit/react-pkuvmt-5nexde?file=app/main.jsx
Regards,
Stefan
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Thanks Stefan,
You mentioned that the messages can be customised, could you please show me how to do that?
Kind regards,
David
Hello, David,
Yes, this can be done by combining both examples and changing the value of the message key in the message json file:
https://stackblitz.com/edit/react-vetqgz?file=app%2Fmain.jsx
If you load a file it will show the custom message associated with the invalidFiles key:
{
"upload": {
"cancel": "Отмени",
"clearSelectedFiles": "Изчисти",
"dropFilesHere": "Пусни фаиловете тук за качване",
"headerStatusUploaded": "Готово",
"headerStatusUploading": "Качване...",
"invalidFileExtension": "Този тип фаил не е позволен.",
"invalidFiles": "This is my custom message for invalid files",
Regards,
Stefan
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Thanks Stefan,
In terms of implementing custom messages for an Upload component used repeatedly throughout a production app would best practice be to wrap the entire App in the LocalizationProvider and IntlProvider, and loadMessages there to avoid repeated loads?
Kind regards,
David
Hello, David,
Yes, this is the recommended approach. We advise using these provides on a lower level only if they have to be applied on specific components without affecting the others. In all other cases, we can recommend using both providers on a top-level in order to affect all components from a single place.