I'm trying to add a image upload feature to react-draft-wysiwyg editor.
As per the editor documentation,
image: uploadCallback: This is image upload callBack. It should return a promise that resolves to give image src. Default value is true. Both above options of uploadEnabled and uploadCallback should be present for upload to be enabled. Promise should resolve to return an object { data: { link: <THE_URL>}}.
Source : https://jpuri.github.io/react-draft-wysiwyg/#/docs
The problem I'm facing is that, while uploading the image to firebase, and the resultant url, I'm trying to use it to create this object for returning from this callback.
Here, in code, firstly image is being uploaded using uploadBytes method of firebase, then using getDownloadURL, we are getting the url of the file. There is a bug that the object with undefined url link is being returned from the callback.
const uploadImageCallBack = (file) => {
let linkImg = "";
let arr = [];
const saveImagePromise = new Promise((resolve, reject) => {
const fileNameParts = file.name.split(".");
const storage = getStorage(app);
const storageRef = ref(
storage,
"Random/" +
title +
"/editorImage." +
uuidv4() +
fileNameParts[fileNameParts.length - 1]
);
debugger;
const metadata = {
contentType: file.type,
};
try {
const uploadTask = uploadBytes(storageRef, file, metadata);
debugger;
uploadTask.then((snapshot) => {
debugger;
const downloadURLPromise = getDownloadURL(storageRef);
downloadURLPromise.then((url) => {
linkImg = url;
debugger;
});
arr.push(downloadURLPromise);
});
arr.push(uploadTask);
} catch (error) {
console.log(error);
reject(error);
}
});
arr.push(uploadBytes, saveImagePromise);
console.log(Infinity);
Promise.all(arr).then((res) => {
console.log(res);
console.log(Infinity);
return new Promise((resolve, reject) => {
resolve({ data: { link: linkImg } });
});
});
};
and the code for editor is
<Editor
toolbar={{
inline: { inDropdown: true },
list: { inDropdown: true },
textAlign: { inDropdown: true },
link: { inDropdown: true },
history: { inDropdown: true },
image: {
urlEnabled: true,
uploadEnabled: true,
alignmentEnabled: true,
uploadCallback: uploadImageCallBack,
previewImage: true,
inputAccept:
"image/gif,image/jpeg,image/jpg,image/png,image/svg",
alt: { present: true, mandatory: false },
defaultSize: {
height: "auto",
width: "auto",
},
},
}}
onContentStateChange={(data) => {
let res = convertToPlain(draftToHtml(data));
console.log(data);
setReasonProgress(
remainigchar >= 100 ? 100 : remainigchar
);
}}
wrapperClassName="wrapper-class"
editorClassName="editor-class"
toolbarClassName="toolbar-class"
/>```
Please help me to create a correct return statement.
I solved this problem by using async function and adding wait statement for the url.
const uploadImageCallBack = async (file) => {
const fileNameParts = file.name.split(".");
const storage = getStorage(app);
const storageRef = ref(
storage,
uuidv4() +
fileNameParts[fileNameParts.length - 1]
);
let imageObject = {
file: file,
localSrc: URL.createObjectURL(file),
};
const metadata = {
contentType: file.type,
};
const snapshot = await uploadBytes(storageRef, file, metadata);
const url = await getDownloadURL(storageRef);
console.log(url, snapshot);
return new Promise((resolve, reject) => {
resolve({ data: { link: url } });
});
};