Sean Mahoney
Sean Mahoney

Reputation: 131

Simple API endpoint in NodeJs

I'm trying to write a very simple API endpoint for a Udacity project I'm working on. When I try postman against the below endpoint, I get a promise rejection warning. I first attempted this using the 3 commented lines within this endpoint, but since it ran asynchronously, the file would not be ready before the delete function would run resulting in a file not found.

Any suggestions?

  app.get( "/filteredimage", async ( req, res ) => {
    var re = req.query.image_url;
    if (!re){
      return res.status(400).send(`id is required`);
    }
    var myfun = function (data, callback) {
      var filteredpath = filterImageFromURL(data);
      callback([filteredpath]);
    };

    myfun(re,deleteLocalFiles);

    // let filteredpath = filterImageFromURL(re);
    // res.sendFile(filteredpath);
    // deleteLocalFiles([filteredpath]);
  } );

Here are the util functions:


export async function filterImageFromURL(inputURL: string): Promise<string>{
    return new Promise( async resolve => {
        const photo = await Jimp.read(inputURL);
        const outpath = '/tmp/filtered.'+Math.floor(Math.random() * 2000)+'.jpg';
        await photo
        .resize(256, 256) // resize
        .quality(60) // set JPEG quality
        .greyscale() // set greyscale
        .write(__dirname+outpath, (img)=>{
            resolve(__dirname+outpath);
        });
    });
}

// deleteLocalFiles
// helper function to delete files on the local disk
// useful to cleanup after tasks
// INPUTS
//    files: Array<string> an array of absolute paths to files
export async function deleteLocalFiles(files:Array<string>){
    for( let file of files) {
        fs.unlinkSync(file);
    }
}

Upvotes: 0

Views: 310

Answers (1)

selfagency
selfagency

Reputation: 1578

Not much for TypeScript but I see a few issues:

One, you don't have to put a Promise in an async function because an async function is a Promise. Two, you're not awaiting filterImageFromURL() properly. And three, you should use try/catch blocks so that you don't get Unhandled Promise Rejection errors.

Forgive my stripping out of your TS.

app.get( "/filteredimage", async ( req, res ) => {
  var myfun = async function (data, callback) {
    try {
      var filteredpath = await filterImageFromURL(data);
      callback([filteredpath]);
    } catch(err) {
      console.error(err);
    }
  };

  try {
    var re = req.query.image_url;

    if (!re) {
      return res.status(400).send(`id is required`);
    }

    await myfun(re, deleteLocalFiles);

    // let filteredpath = filterImageFromURL(re);
    // res.sendFile(filteredpath);
    // deleteLocalFiles([filteredpath]);
  } catch(err) {
    console.error(err);
  }
});
export async function filterImageFromURL(inputUR) {
  try {
    const photo = await Jimp.read(inputURL);
    const outpath = '/tmp/filtered.'+Math.floor(Math.random() * 2000)+'.jpg';
    const img = photo
      .resize(256, 256) // resize
      .quality(60) // set JPEG quality
      .greyscale() // set greyscale
      .write(__dirname+outpath);
    return img
  } catch(err) {
    console.error(err);
  }
}

Upvotes: 2

Related Questions