Reputation: 13
I have a NodeJS and React project. I am having a problem. I didnt understand what the problems are. First I want to show you what my problem is.
on localhost. I want like this on heroku but it returns me as the next one
My problem's photo:
As you see on the photo there is an html file in my user object on Heroku deployment.
But when I start my project on localhost the user has an object that is coming from my mongo database. Express.json() is catching and working correctly on localhost but it doesnt work on Heroku. Why does it happen? What is my problem?
Here is my server.js file :
const express = require("express");
const path = require("path");
const app = express();
const connectDB = require("./config/db");
const PORT = process.env.PORT || 5000;
connectDB();
app.use(express.json());
app.use(express.json({ extended: false }));
app.use(express.static("client/build"));
if (process.env.NODE_ENV === "production") {
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
}
app.use("/", require("./routes/quizRoute"));
app.use("/users", require("./routes/userRoute"));
app.use("/auth", require("./routes/authRoute"));
app.listen(PORT, () => {
console.log("Server is started on the port " + PORT);
});
Client Side request
//SET AUTH WORK
import axios from "axios";
const setAuthToken = token => {
if (token) {
axios.defaults.headers.common["x-auth-token"] = token;
} else {
delete axios.dafaults.header.common["x-auth-token"];
}
};
export default setAuthToken;
//LOAD USER
const loadUser = async () => {
if (localStorage.token) {
setAuthToken(localStorage.token);
}
try {
const res = await axios.get("/auth");
dispatch({ type: USER_LOADED, payload: res.data });
} catch (err) {
dispatch({
type: AUTH_ERROR,
payload:
"AUTH_ERROR: Token dogrulanamadi veya /auth'a GET isteginde bir sorun var"
});
}
};
enter code here
Upvotes: 0
Views: 140
Reputation: 2573
Why you are having the issue:
I believe your bundler sets the NODE_ENV
value to production
when it builds for the deploy environments i.e Heroku. So you are having this issue because of the catch-all route that sends back your client index.html
on every get request:
if (process.env.NODE_ENV === "production") {
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
}
Consequently, when you make the get request to the /auth
route from your client app, the request gets intercepted by this catch-all route handler before getting to the expected route handler. I'm pretty certain you would get back that HTML string whenever you make any get request to your server, not just the for /auth
The solution:
The easy fix for this would be for you to move the catch-all route below your API routes like this:
app.use("/", require("./routes/quizRoute"));
app.use("/users", require("./routes/userRoute"));
app.use("/auth", require("./routes/authRoute"));
// Every other API or similar routes should be before this catch-all
if (process.env.NODE_ENV === "production") {
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
}
Upvotes: 1