Visit The School

Deleting Objects From Amazon S3 With Node

Alexander Paterson
|
Posted 6 months ago
|
3 minutes
Deleting Objects From Amazon S3 With Node
We'll be using the Node AWS SDK

The AWS Javascript SDK actually does have quite good documentation, it's just harder than it should be to find. Here's the section on the S3.deleteObject function.

So, if in Developing And Deploying Mobile Backend API's With Node.js, you wanted to have the images associated with to-do's deleted from the S3 bucket upon the removal of the todo, I would do this using a function that looks like this:

// services/s3.js

exports.destroyTodoImage = function(filename, callback) {
  var s3 = new aws.S3();
  var params = {
    Bucket: 'xxx',
    Key: filename
  };
  s3.deleteObject(params, function(err, data) {
    if (err) {
      console.log(err);
      callback(err);
    } else {
      callback(null);
    }
  });
}

Which I'd call in TodosController.destroy, like this:

// controllers/todos_controller.js

exports.destroy = function(req, res, next) {
  var user = req.user;
  var id = req.params.todo_id;

  var removedTodo; // This is so we can grab the imageURL of the removed todo
  user.todos = user.todos.filter((todo) => {
    if (todo._id == id) {
      removedTodo = todo; // and this
      return false;
    } else {
      return true;
    }
  });

  // The removedTodo may or may not actually have an image associated with it
  var filenameToRemove;
  if (removedTodo.imageURL && removedTodo.imageURL !== "") { // check
    // If the imageURL looks like: 'http://cxcxzzcx.whatever.com/32123321.jpg'
    // this just grabs the '32123321.jpg'
    filenameToRemove = removedTodo.imageURL.split('/').slice(-1)[0];
  }

  // I'd rather not repeat this code
  var onFileRemoveComplete = function() {
    user.save(function(err) {
      if (err) { return next(err) }
      res.status(200).json({success: "Successfully destroyed todo."});
    });
  }

  // Only remove image if there's one to remove
  if (filenameToRemove) {
    s3.destroyTodoImage(filenameToRemove, function(err) {
      if (err) { return next(err) }
      onFileRemoveComplete();
    });
  } else {
    onFileRemoveComplete();
  }
}

Now, I haven't tested this code at all, but I'm pretty sure it's all good. Let me know in the comments where the typos are.

You might not want to make the user wait for the image to be deleted, in which case you could call res.status.json before calling s3.destroyTodoImage. In this case, be aware that calling next or touching res in the callback to s3.destroyTodoImage will cause your express server to throw an exception; you'd have to come up with a backend system if you wanted to ensure the image was deleted.

In many cases, deleting old images is pointless anyway. Amazon S3 costs only cents per month per gigabyte of storage; about 30,000 profile pictures would cost you $1/month to store.



ALEXANDER
PATERSON