How do I return a promise in a Node.js view?

Issue

In my backend, I make an api call to a third party website that returns a promise. I need to pass that promise to an html template, however using JSON.stringify() in the backend and then JSON.parse() in the frontend didn’t work. I received this error:

JSON.parse: unexpected character at line 1 column 2 of the JSON data

So I’ve decided to change my strategy and do a fetch request from the html template to my Node.js server. This is my current code:

async function getItems() {
    return await api.Items
    ...
}

app.get('/getItems', function(req, res){
    res.end(Buffer.from(getItems()));
});

The problem I’ve run into is that I can’t return a promise with res.end, even with Buffer:

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

I also tried:

app.get('/getItems', function(req, res){
    getItems().then(result=> 
        {
            res.end(result);
        }   
    ).catch(err => 
        {
            res.status(504);
        }
    )
});

However the connection times out with a 504 status.

How do I make the view return a promise?

Edit: In the second example, where I get the result of the promise, it doesn’t time out if I set it to res.end(‘5’).

Edit again:

const items = fetch('127.0.0.1/api'); 
console.log(items);
for (const item of items) { console.log(item); }

Response { type: "basic", url: "127.0.0.1/api", redirected: false, status: 200, ok: true, statusText: "OK", headers: Headers, body: ReadableStream, bodyUsed: false }

Uncaught (in promise) TypeError: items is not iterable

Solution

You have to wait for the promise to resolve and THEN send the response. There are a couple ways to do it:

app.get('/getItems', function(req, res){
    getItems().then(result => {
        res.json(result);
    }).catch(err => {
        console.log(err);
        res.sendStatus(500);
    });
});

This would send your items as JSON which is presumably more useful than sending a buffer.


Or, you can use async/await like this:

app.get('/getItems', async function(req, res){
    try {
        const result = await getItems();
        res.json(result);
    } catch(err) {
        console.log(err);
        res.sendStatus(500);
    }
});

Answered By – jfriend00

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published