Cloudinary and Postgresql - Deleting and Updating Images Using Nodejs
Tags: postgres, cloudinary, node, images
Published: 2020-05-13 01:52:08

Welcome 🤗 to the concluding part of this tutorial. It's being a long roll. We are now able to see ``nodejs``, ``cloudinary`` and ``postgresql`` as 3 persons working together to solve our problem.

[Getting Started](#1)
[Creating APIs](#2)
[Delete API](#3)
[Update API](#4)

We started with the introductory part on [Setting Up a Simple, Secure and Robust Node JS Server](https://dev.to/ebereplenty/setting-up-a-simple-secure-and-robust-node-js-server-10n0) up to [Persisting and Retrieving images using cloudinary and Postgresql Through Nodejs](https://dev.to/ebereplenty/cloudinary-and-postgresql-persisting-and-retrieving-images-using-nodejs-31b2). 

Today we want to look at *deleting* and *updating* images on cloudinary.

<a name="1"></a>
### Getting Started

As a prerequisite to this tutorial, please take the [last tutorial](https://dev.to/ebereplenty/cloudinary-and-postgresql-persisting-and-retrieving-images-using-nodejs-31b2) to be up to speed. 

If you are coming from the previous tutorial, then move to [Creating APIs](#2). 

However, if you are just joining us, please find the starter project for this tutorial [here](https://github.com/EBEREGIT/server-tutorial).

**At this point, I want to believe that we are all up to speed!!!**

Now to the business of the article...

<a name="2"></a>
## Creating APIs

<a name="3"></a>
### Delete API
* In the app.js file, start with the following code

```javascript

// delete image
app.delete("delete-image/:cloudinary_id", (request, response) => {

});

```

* Next, we want to get the unique ID of the image we want to delete from the URL i.e ``cloudinary_id``. So inside the code above add:

```javascript

const { cloudinary_id } = request.params;

```

*We now start the deleting process* 

* First, we delete from the cloudinary. Add the following code to delete the image from cloudinary

```javascript

cloudinary.uploader
    .destroy(cloudinary_id)
    .then((result) => {
      response.status(200).send({
        message: "success",
        result,
      });
    })
    .catch((error) => {
      response.status(500).send({
        message: "Failure",
        error,
      });
    });

```

*At this point, our API can delete the image from cloudinary only (You can check it out in postman). However, we want to also get rid of the record we have in our postgres database*

* Second, we delete from our postgres database. To do so, replace the code in the ``then`` block with the following ``query``:

```javascript

db.pool.connect((err, client) => {
     
      // delete query
      const deleteQuery = "DELETE FROM images WHERE cloudinary_id = $1";
      const deleteValue = [cloudinary_id];

})
```

* Execute the query with the following code underneath it:

```javascript

// execute delete query
      client.query(deleteQuery, deleteValue)
      .then((deleteResult) => {
        response.status(200).send({
          message: "Image Deleted Successfully!",
          deleteResult
        });
      }).catch((e) => {
        response.status(500).send({
          message: "Image Couldn't be Deleted!",
          e
        });
      });

```

So our API should look like this:

```javascript

// delete image
app.delete("/delete-image/:cloudinary_id", (request, response) => {
  // unique ID
  const { cloudinary_id } = request.params;

  // delete image from cloudinary first
  cloudinary.uploader
    .destroy(cloudinary_id)

    // delete image record from postgres also
    .then(() => {
      db.pool.connect((err, client) => {
     
      // delete query
      const deleteQuery = "DELETE FROM images WHERE cloudinary_id = $1";
      const deleteValue = [cloudinary_id];

      // execute delete query
      client
        .query(deleteQuery, deleteValue)
        .then((deleteResult) => {
          response.status(200).send({
            message: "Image Deleted Successfully!",
            deleteResult,
          });
        })
        .catch((e) => {
          response.status(500).send({
            message: "Image Couldn't be Deleted!",
            e,
          });
        });
      })
    })
    .catch((error) => {
      response.status(500).send({
        message: "Failure",
        error,
      });
    });
});

```

**The time has arrived for us to put our API to the test.** 

The following is my cloudinary ``media library`` with two images I uploaded already. Take note of their unique ID (``public_id``). We discussed this in the previous tutorials.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sjir185on5pqrlzrc1hl.JPG)

If you don't already have that, please use the persist-image API to upload some images.

Now let's proceed to postman

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/beu5lleymnffa5vyzj97.JPG)

Notice, the unique ID as it matches one of the image in my cloudinary media library.

From the output, we executed the DELETE command and that deleted one ROW from our  image TABLE in our database.

Now this is my media library with one of the images remaining:

<a name="6"></a>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8d7rs33580c4ewpcipbr.JPG)

Walahhhh... We are now able to get rid of an image. 

Do take a break if you desire one. ✌🏾

![Coffee Break](https://media.giphy.com/media/pC5kJnZTt4MvK/giphy.gif)

If you are ready, I am ready to update images

<a name="4"></a>
### Update Image API
* Below the ``delete-image`` API, let's start creating the ``update-image`` API with the following code:

```javascript

// update image
app.put("/update-image/:cloudinary_id", (request, response) => {

});

All codes will live in there.

```

* Collect the unique cloudinary ID and new image details from the user with the following code:

```javascript

// unique ID
  const { cloudinary_id } = request.params;

// collected image from a user
  const data = {
    title: request.body.title,
    image: request.body.image,
  };

```

* Delete the image from cloudinary with the following code

```javascript

// delete image from cloudinary first
  cloudinary.uploader
    .destroy(cloudinary_id)
      // upload image here
    .then()
    .catch((error) => {
      response.status(500).send({
        message: "failed",
        error,
      });
    });

```

* Next, upload another image to cloudinary. To do that, enter the following code into the then block

```javascript

() => {
      cloudinary.uploader
        .upload(data.image)
        .then()
        .catch((err) => {
          response.status(500).send({
            message: "failed",
            err,
          });
        });
    }

```

* Now let's replace our initial record with the new image details. Replace the content of the ``then`` block with the following:

```javascript

(result) => {
          db.pool.connect((err, client) => {
            
            // update query
            const updateQuery =
              "UPDATE images SET title = $1, cloudinary_id = $2, image_url = $3 WHERE cloudinary_id = $4";
            const value = [
              data.title,
              result.public_id,
              result.secure_url,
              cloudinary_id,
            ];
          });
        }

```

* We execute the query using the following code just beneath the query declaration

```javascript

// execute query
            client
              .query(updateQuery, value)
              .then(() => {

                // send success response
                response.status(201).send({
                  status: "success",
                  data: {
                    message: "Image Updated Successfully"
                  },
                });
              })
              .catch((e) => {
                response.status(500).send({
                  message: "Update Failed",
                  e,
                });
              });

```

At this point, this is what I have

```javascript

// update image
app.put("/update-image/:cloudinary_id", (request, response) => {
  // unique ID
  const { cloudinary_id } = request.params;

  // collected image from a user
  const data = {
    title: request.body.title,
    image: request.body.image,
  };

    // delete image from cloudinary first
    cloudinary.uploader
      .destroy(cloudinary_id)

      // upload image here
      .then(() => {
        cloudinary.uploader
          .upload(data.image)

          // update the database here
          .then((result) => {
            db.pool.connect((err, client) => {
            // update query
            const updateQuery =
              "UPDATE images SET title = $1, cloudinary_id = $2, image_url = $3 WHERE cloudinary_id = $4";
            const value = [
              data.title,
              result.public_id,
              result.secure_url,
              cloudinary_id,
            ];

            // execute query
            client
              .query(updateQuery, value)
              .then(() => {

                // send success response
                response.status(201).send({
                  status: "success",
                  data: {
                    message: "Image Updated Successfully"
                  },
                });
              })
              .catch((e) => {
                response.status(500).send({
                  message: "Update Failed",
                  e,
                });
              });
            });
          })
          .catch((err) => {
            response.status(500).send({
              message: "failed",
              err,
            });
          });
      })
      .catch((error) => {
        response.status(500).send({
          message: "failed",
          error,
        });
      });
  
});

```

**It's Testing Time!!!**

This is my postman in the image below:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jowr0guiazmqkhx1mmls.JPG)

Take note of the unique cloudinary ID which matches the image left in my cloudinary media library.

Now take a look at my cloudinary media library in the image that follows:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/td9rpqovhh2kl6ytc2u4.JPG)

Take note of the new image replacing the initial one in my media library [above](#6)

Also, see that the unique clodinary ID matches that in my database with the new title. See image below:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wu3mydrn71x3azyd75ee.JPG)

Yayeh!!!

You did awesomely great!!! 💪

We just completed a CRUD application with nodejs, cloudinary and postgresql!!!

### Conclusion
We have been able to complete what we started a couple of months ago - *A CRUD App*. If you started from the [beginning](https://dev.to/ebereplenty/setting-up-a-simple-secure-and-robust-node-js-server-10n0) with us, then you will see that we started from nothing but now we are dinning with not just **nodejs** but **cloudinary** and **postgres**.

All codes can be found [here](https://github.com/EBEREGIT/server-tutorial/tree/delete-and-update-API)

{% github EBEREGIT/server-tutorial %}

Please keep up the good learning!!!

![Thumbs Up](https://media.giphy.com/media/LnuVjR9D2So3WxdLkZ/giphy.gif)

You will notice that our App.js file is now too long and we are getting lost in our code. That is going to be fixed in the next article where we will be doing something nice on [Nodejs Code Structure Optimization With Express Routing](https://dev.to/ebereplenty/nodejs-code-structure-optimization-with-express-routing-5fna).

If you have questions, comments or suggestions, please drop them in the comment section.

You can also follow and message me on social media platforms. 

**[Twitter](https://twitter.com/eberetwit) | [LinkedIn](https://www.linkedin.com/in/samson-ebere-njoku-profile/) | [Github](https://github.com/EBEREGIT)**

Thank You For Your Time.