Deleting Images
Basics
There are two ways to delete an image, and both should be used in your app. Each of these cases are used in different scenarios. Often, you will be removing images from the client side when you are pushing the delete button or even removing old images, and this should use the client version. The Image Core addon, when it was installed has added a route to the router called remove/image
that takes an id and handles deleting the image with that id from the database. In essence, you will make a direct server request to delete the image. It is important to note, however that once this remove is called to the database, there is no getting that image back. Below describes how to properly ensure the images only are truly deleted when the user wants them to be. However, when deleting a model, which is linked to an image, you will need to make sure you delete the image before deleting its parent model, and this is done using the serverside version of deleting an image.
Note: Remember from uploading images that there are times when you need to remove images that have been uploaded even if they don't appear to be fully saved.
Client Side Handling
Deleting, like uploading is a fairly simple process. In order to determine if you wish to use basic or data cleanup version of this, make sure to ask yourself the question, as detailed in uploading images.
Handlebars File
The only thing to say here is to make sure that you have a button to delete images under the display for each image. For details displaying an image, see displaying an image. It is also important, if you are doing the data cleanup way, that you do not call an action that calls the removeUrl
, but rather calls a "halfway" delete, so that your action is cancelable.
Javascript File
Javascript requires a couple of things to be set up.
Basic
At the basic level, deleting an image simply involves setting up and calling the removeUrl for the image, and is even simpler than uploading it.
removeUrl: computed('config.apiRoot', 'currentUser.currentDept', function () {
return this.get('config').formUrl('remove', 'image');
}),
actions: {
removeImage(image) {
let removeUrl = this.get('removeUrl');
return RSVP.resolve(this.get('ajax').post(removeUrl, {data: image}));
}
}
This will delete the image, and it will no longer be in the database, but this cannot be undone.
Including with Cleanup
One of the important aspects of making sure this part works correctly is making sure you follow the data cleanup instructions on uploading images. After having done that, there are two steps to actually delete images.
The first step is not using the actual delete url with the delete button, but making a partiallyDeleteImage
function. The idea with this function is that it should simply add the image to the imagesToDeleteUponSave
array, instead of actually deleting it (because if you cancel, then it shouldn't be deleted). For example:
actions: {
//single image
partiallyDeleteImage(imageId) {
this.get('imagesToDeleteUponSave').pushObject(imageId);
this.set('model.image', null);
},
//multiple images
partiallyDeleteImage(imageId) {
this.get('imagesToDeleteUponSave').pushObject(imageId);
this.set('model.images').removeObject(imageId);
}
}
Then, finally, you must also persist your changes whenever you save or delete an array. For example:
actions: {
save() {
// whatever other aspects
let promises = [this.get('model').save()];
let removeUrl = this.get('removeUrl');
this.get('imagesToDeleteUponSave').forEach((image) => {
promises.pushObject(this.get('ajax').post(removeUrl, {data: image}));
});
return RSVP.all(promises);
},
cancel() {
// whatever other aspects also make sure to revert model changes as well
let promises = [];
let removeUrl = this.get('removeUrl');
this.get('imagesToDeleteUponCancel').forEach((image) => {
promises.pushObject(this.get('ajax').post(removeUrl, {data: image}));
});
return RSVP.all(promises);
}
}
After you have done all these steps, it should work that your database stays clean even if your end user uploads six images before saving, and you won't have issues if a user deletes and image, then changes their mind.
Server Side Handling
The serverside aspect of this deleting is fairly simple, and it is also part of making sure data is clean. If you delete a model with an image, you should delete the image as well. Make sure at the top of your file you use ImageCore/ImageModel;
, then edit the delete function to include the following:
public function delete($options) {
// ... whatever other code you need
//delete any image associated with the item
$item = $this->adapter->findById('Item', $options->id);
if($item->get('image')) {
ImageModel::delete($item->get('image'));
}
$this->adapter->delete('Item', $options->id);
}
Using this serverside way of deleting allows the database to be clean of unlinked images.