Search code examples
javascriptnode.jsexpressaxios

Localhost didn't send any data in my Node/Express/Axios app


I'm working on a full-stack Node app using Express, with Axios to make a call to an external API. My API call is working, but it doesn't seem to send any data back to my route handler and I'm getting a browser timeout and then the message:

"localhost didn't send any data ERR_EMPTY_RESPONSE"

Here is my route handler, routes/met_route.js:

'use strict';
import express from "express";
import metData from "../models/metData.js";

const router = express.Router();
router.get('/', metData.searchArt, (req, res) => {
    res.send(res.data)
})

export default router;

And here is my code with the API call, models/metData.js:

'use strict';
import axios from "axios";

const metAPI = {
   searchArt: function() {
      axios.get("https://collectionapi.metmuseum.org/public/collection/v1/objects/11")
         .then(response => {
            console.log(response.data)
         })
         .catch(error => console.error('error:', error));
   }
};

export default metAPI;

My main server.js file is as follows:

import express from "express";
import cors from "cors";
import homeRoute from "../routes/home_route.js";
import metRoute from '../routes/met_route.js';

const PORT = process.env.PORT || 5050;
const app = express();

app.use(cors());
app.use(express.json());

//routing
app.use("/", homeRoute);
app.use("/met", metRoute);

// start the express server
app.listen(PORT, ()=> {
    console.log(`server listening on port ${PORT}`);
});

The route /met works fine as long as I don't make a router.get request to my models/metData.js file, but once I make that request I am getting the error above. I am wondering if it could be an async issue. Any insight would be greatly appreciated.


Solution

  • Your searchArt function doesn't do anything with the response other than log it. It's also invalid as an Express middleware function because it never calls next() (see https://expressjs.com/en/guide/writing-middleware.html).

    It seems to me that your searchArt function should instead simply return a promise resolving with the data you want. You can call this function directly from your route handler, there's no need to try and use it as middleware

    const metAPI = {
      async searchArt() {
        return (
          await axios.get(
            'https://collectionapi.metmuseum.org/public/collection/v1/objects/11',
          )
        ).data;
      },
    };
    
    // Express v5
    router.get('/', async (req, res) => {
      res.send(await metData.searchArt());
    });
    
    // or
    
    // Express v4
    router.get('/', async (req, res, next) => {
      try {
        res.send(await metData.searchArt());
      } catch (err) {
        next(err);
      }
    });
    

    See the error handling guide for information on the differences between v4 and v5 when it comes to async functions.