.map is not a function when getting React files from build folder

Issue

I have a node/express application that’s using React for the frontend. Everything works fine in development mode where there’s a proxy between the backend running on localhost:5000 and the frontend on localhost:3000. However, I’m running into an issue for my production build where I’m getting the static React files from the build folder by including the following in my main server file:

app.use(express.static(path.join(__dirname, "client", "build")));
app.get("*", function (req, res) {
  res.sendFile("index.html", {
    root: path.join(__dirname, "client", "build"),
  });
});

With this setup, I’m able to see the React app on localhost:5000, but on certain routes/pages I receive TypeError: a.map is not a function. The errors all seem to be triggered by arrays that are created in a context provider that sets state from APIs using axios. Here’s an example of one of the API calls:

  const getNodesApi = {
    url: "model/get-all-nodes",
    method: "GET",
    headers: {
      token: localStorage.token,
    },
  };
  async function getNodeData() {
    await axiosPm(getNodesApi)
      .then((response) => {
        const resData = response.data;
        setNodeData(resData);
        setLoading(false);
      })
      .catch((error) => {
        console.log(error.response);
      });
  }

Is there something I have to do to set the base URL for the APIs or could something else be causing the TypeError: a.map is not a function?

Edit 1: Example where .map is failing

  const [options, setOptions] = useState(
    processes.map((process, index) => ({
      key: index,
      value: process.process_id,
      label: process.process_name,
    }))
  );

In this example processes is coming from the context provider. It’s initially defined by:

const [processes, setProcesses] = useState([]);

Solution

Answering my own question for visibility. The issue was being caused because I was mounting my backend/API routes after doing app.get for the React index.html. To resolve, mount the backend routes first.

app.use(express.static(path.join(__dirname, "client", "build")));

//Routes - mounted from backend for API
mountRoutes(app);

//Routes - use from React app for frontend
app.get("*", function (req, res) {
  res.sendFile("index.html", {
    root: path.join(__dirname, "client", "build"),
  });
});

Answered By – userNick

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