Home > Back-end >  Trouble w/ returning random image in my custom API
Trouble w/ returning random image in my custom API

Time:11-24

I'm working on my own api, using Express and Node JS and im making something that returns funny cat images. Heres where i am with the random funny cat images.

app.get("/media/bigfootjinx", (req, res, next) => {
    let file = Math.floor(Math.random()*catarray.length)
        let fileurl = catarray[file]
        let fileimg = fetch(fileurl)
    let img = Buffer.from(fileimg, 'base64');
    res.writeHead(200, {
        'Content-Type': 'image/png',
        'Content-Length': img.length
    });
    res.end(img); 
});

My goal is to get a random cat image back, they are all in pngs and links to a discord cdn. The error im constantly getting is this.

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received an instance of Promise
    at Function.from (buffer.js:330:9)
    at /home/runner/api/index.js:21:22
    at Layer.handle [as handle_request] (/home/runner/api/node_modules/express/lib/router/layer.js:95:5)
    at next (/home/runner/api/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/home/runner/api/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/home/runner/api/node_modules/express/lib/router/layer.js:95:5)
    at /home/runner/api/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/home/runner/api/node_modules/express/lib/router/index.js:335:12)
    at next (/home/runner/api/node_modules/express/lib/router/index.js:275:10)
    at expressInit (/home/runner/api/node_modules/express/lib/middleware/init.js:40:5)

I am using a replit node.js project, if anyone was curious.

CodePudding user response:

fetch is a promise, so you need to await the fetch and return a blob response

app.get("/media/bigfootjinx", async (req, res, next) => {
    let file = Math.floor(Math.random()*catarray.length)
        let fileurl = catarray[file]
        let response = await fetch(fileurl)
        let fileimg = await response.blob()
    let img = await blobToBase64(fileimg);
    res.writeHead(200, {
        'Content-Type': 'image/png',
        'Content-Length': img.length
    });
    res.end(img); 
});

the conversion from blob to base64 function:

function blobToBase64(blob) {
  return new Promise((resolve, _) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result);
    reader.readAsDataURL(blob);
  });
}

CodePudding user response:

The following lines of code are causing the error:

let img = Buffer.from(fileimg, 'base64');
let fileimg = fetch(fileurl)

The fetch() function returns a Promise<Buffer>. You will just have to wait for the fetch results. This you can achieve like that:

let fileimg = await fetch(fileurl)
let img = Buffer.from(fileimg, 'base64');

Note: Your callback function for the get endpoint has to be asynchronous:

app.get("/media/bigfootjinx", async (req, res, next) => {
  • Related