API resolved without sending a response in Nextjs

40,343

Solution 1

You should return a Promise and resolve/reject it.

Example:

import { getData } from "../../helper";

export default async function(req, res) {
  return new Promise((resolve, reject) => {
    getData()
      .then(response => {
        res.statusCode = 200
        res.setHeader('Content-Type', 'application/json');
        res.setHeader('Cache-Control', 'max-age=180000');
        res.end(JSON.stringify(response));
        resolve();
      })
      .catch(error => {
        res.json(error);
        res.status(405).end();
        resolve(); // in case something goes wrong in the catch block (as vijay commented)
      });
  });
};

Solution 2

import { getData } from "../../helper";

export default async function (req, res) {
  try {
    const response = await getData();
    res.statusCode = 200;
    res.setHeader('Content-Type', 'application/json');
    res.setHeader('Cache-Control', 'max-age=180000');
    res.end(JSON.stringify(response));
  }

  catch (error) {
    res.json(error);
    res.status(405).end();
  }
}

Solution 3

For me it was necessary to return the result, even though the result was given to the client without return:

Incorrect: res.status(405).json({ message: 'Method not allowed.' });

Correct: return res.status(405).json({ message: 'Method not allowed.' });

Share:
40,343

Related videos on Youtube

Phil
Author by

Phil

Updated on May 01, 2022

Comments

  • Phil
    Phil about 2 years

    I have to make same changes in my nextjs project because my enpoint API doesn't support many calls and I would like to make a refresh from the original data every 3 min.

    I implemented API from nextjs: I create a pages/api/data and inside I make the call to my endpoint, and in my getInitialProps inside index call to data file.

    The get works okey, but I have 2 problems:

    1: I have and alert message that says:

    API resolved without sending a response for /api/data, this may result in stalled requests.

    2: It dosen 't reload data after 3 min..I supouse it is beacuse Cache-Control value...

    This is my code:

    pages/api/data

    import { getData } from "../../helper";
    
    export default async function(req, res) {
      getData()
        .then(response => {
          res.statusCode = 200
          res.setHeader('Content-Type', 'application/json');
          res.setHeader('Cache-Control', 'max-age=180000');
          res.end(JSON.stringify(response))
        })
        .catch(error => {
          res.json(error);
          next();
        });
    };
    

    pages/index

    import React, { useState, useEffect } from "react";
    import fetch from 'isomorphic-unfetch'
    
    const Index = props => {
    
      return (
        <>Hello World</>
      );
    };
    
     Index.getInitialProps = async ({ res }) => {
      const response = await fetch('http://localhost:3000/api/data')
      const users = await response.json()
      return { users }
    };
    
    export default Index;
    
    • Alessio Marchi
      Alessio Marchi about 4 years
      have you tried to await getData()?
    • Phil
      Phil about 4 years
      Hi Alessio, I try whit the await and the alert message disappear! but the data returns 4 time now...
  • Vijay
    Vijay almost 4 years
    Code snipped in the answer might throw UnhandledPromiseRejectionWarning if there is an error. In the catch block you should do: res.status(405).end(); return resolve()
  • jmealy
    jmealy over 3 years
    Returning a promise from an async function is redundant. Better to use await on getData, ditch all the nesting, and return whatever values you please rather than resolveing.
  • Naxos84
    Naxos84 over 3 years
    I totally aggree that returning an explicit Promise is not always necessary in in an async function. But in my opinion there is nothing useful to return if we're using await. The thing here is that NextJS only wants some return value from that function it doesn't matter what it is. Returning something like data.someValue might be confusing here.
  • chrisheyn
    chrisheyn about 3 years
    I had the same error. I forgott to add await in front of an async function inside my api default function.
  • johndpope
    johndpope over 2 years
    .end() fixed it - thanks