image icon indicating copy to clipboard operation
image copied to clipboard

Does it have a delete listener to delete image after I clicked remove from toolbar ?

Open nikitaplanet opened this issue 5 years ago • 20 comments

Now I can upload image to backend, but when I clicked remove block from toolbar, the image won't delete in our database, how can I call my delete api when I clicked the button ?

https://imgur.com/yel1H1F

nikitaplanet avatar Nov 15 '19 04:11 nikitaplanet

I can't delete any block. ( only using backspace which doesn't apply to image blocks ) I've tried the official demo and it doesn't seem to work either. link image

miguelangeltorresfp avatar Nov 23 '19 21:11 miguelangeltorresfp

@miguelangeltorresfp not trying to be facetious, but, the block delete action requires you to click the X button twice. It works that way on the official demo as well and works fine.

If you did indeed click the button twice (ie confirm the delete) could you perhaps share your browser/device info https://whatsmybrowser.org/ so that others can try and replicate the issue?

mpandzo avatar Dec 18 '19 09:12 mpandzo

I'm having the same issue. No problem uploading an image to my server but how can I get the event that I'm deleting one (and so getting the block data that i'm deleting) so that I can also delete from my server? I've been trying to figure out if there's such a thing in the api but with no success

AdrienPVM avatar Jan 23 '20 11:01 AdrienPVM

I'm having the same issue. No problem uploading an image to my server but how can I get the event that I'm deleting one (and so getting the block data that i'm deleting) so that I can also delete from my server? I've been trying to figure out if there's such a thing in the api but with no success

i have the same problem

vitaliybalayan avatar Mar 08 '20 21:03 vitaliybalayan

I am having same issue, is there any OnDelete event I could bind?

Lijef42 avatar May 19 '20 19:05 Lijef42

I'm having the same issue. No problem uploading an image to my server but how can I get the event that I'm deleting one (and so getting the block data that i'm deleting) so that I can also delete from my server? I've been trying to figure out if there's such a thing in the api but with no success

I have the same problem. This problem will increase the cost of storing files because unused files will be stored. This is not economical.

Vendin avatar May 23 '20 12:05 Vendin

Perhaps I'm wrong or didn't found a better solution but onDelete sounds to me like a quick win solution but will create new problemes. Example: While the block can be deleted it doesn't really mean that the editor has performed it's save action. A reload would still have the same block but the image would be removed already.

In my case I did extended the editorjs-core with a unique-id per block (https://github.com/codex-team/editor.js/issues/873) and used this id for a server-side diff which allows me to identify if a block got created, modified, moved or deleted. I'm using this to dispatch specific events and during the delete-event I'm using an async s3 delete operation for the object.

christoph-kluge avatar May 23 '20 12:05 christoph-kluge

@christoph-kluge Yeah that's absolutely correct. But diff is overkill if you just want to delete images. I keep an array called deleted, I append the image_key to it whenever a new image is deleted and send it to backend server only when user saves the editor data.

MohitKS5 avatar Jun 14 '20 01:06 MohitKS5

@MohitKS5 How do you detect that the image is deleted without doing a diff?

cgorrieri avatar Oct 03 '20 20:10 cgorrieri

Hey Guys

I found a solution that worked for me which i will share down here. I'm using VueJS for the project and currently saving images in FirebaseStorage using "uploadByFile" function. The way I'm saving them is by generating a unique UID for each image, attaching it to the name and saving it in the state of the application. In order to detect the deletion of blocks I'm using the onChange listener that comes with EditorJS. In it you can access the current number of block in the editor. I check to see if any was deleted, use javascript to select all the images blocks currently in the editor. I subtract the UID from the name of the image and cross-reference it with the array of imagesUploade saved in the state. If any of them is missing i delete it from Firestore and subsequently from the state. Below is the code for this:

this.editor = new EditorJS({
      onChange: (ev) => {
        if(ev.blocks.getBlocksCount() < that.previousCount)
        {
          let noMatch = [...that.imagesUploaded]
          document.querySelectorAll('.image-tool__image-picture').forEach((img) => {
              let indx = (img.src).match(/images%2F(.*?)\?alt/)[1]
              noMatch.splice(noMatch.indexOf(indx, 1));
          })
          if(noMatch.length == 1)
          {
            storageRef(`${that.sessionId}/images/${noMatch[0]}`).delete()
            that.imagesUploaded.splice(that.imagesUploaded.indexOf(noMatch[0]), 1)
          }
        }
        else{
          that.previousCount = ev.blocks.getBlocksCount()
        }
      }
}

patratel avatar Nov 10 '20 12:11 patratel

Using the idea from @patratel , I did something similar in React.

Basically, I used a custom uploadFile() function in my image config. Whenever an image is uploaded, the url for that image is stored in an array. Each time the change event is triggered in the editor, a change handler function checks if the number of images in the image array is equal to the number of images displayed in the editor. If there are more entries in the images array than there are images in the editor, the function filters out the the extra image url and sends it to the back end with a delete request, where the image gets deleted.

Here's the code:

const [imagesUploaded, setImagesUploaded] = useState([])

// tools config
const tools = {
    paragraph,
    image: {
      class: ImageTool,
      config: {
        uploader: {
          async uploadByFile(file) {
            const formData = new FormData()
            formData.append('image', file)

            try {
              const res = await fetch('/api/upload', {
                method: 'POST',
                body: formData,
              })
              const json = await res.json()

              // keep track of images, add the url of each new image to our array
              setImagesUploaded((x) => [...x, json.file.url])

              return json
            } catch (err) {
              console.log(err.message)
            }
          },
        },
      },
    },
  }

 // change handler
 const handleChange = () => {
    // get all current images in editor
    const currentImages = []
    document
      .querySelectorAll('.image-tool__image-picture')
      .forEach((x) => currentImages.push(x.src.match(/\/api.*$/g)[0]))

    if (imagesUploaded.length > currentImages.length) {
      imagesUploaded.forEach(async (img) => {
        if (!currentImages.includes(img)) {
          try {
            const res = await fetch('/api/upload', {
              method: 'DELETE',
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({ path: img.match(/image.*$/g)[0] }),
            })
            const data = await res.text()
            console.log(data)
            setImagesUploaded((images) => images.filter((x) => x !== img))
          } catch (err) {
            console.log(err.message)
          }
        }
      })
    }
  }

Isaac-Svi avatar Mar 10 '21 13:03 Isaac-Svi