Issue: I'm developing a blood donation-related React Native Expo project, and I'm encountering a routing issue when I try to make a POST request using Axios.
Description:
I have a handleSignup
function in my SignupScreen.js
that sends a POST request to an API endpoint for user registration. Here's the relevant part of the code:
const handleSignup = () => {
const user = {
// user data...
};
axios
.post("http://192.168.66.184:19000/register", user)
.then((response) => {
// Handle response...
})
.catch((error) => {
// Handle error...
});
}
Error: However, when I run my app and press the signup button, I get the following error message: "AxiosError: Request failed with status code 404." When I try to access "http://192.168.66.184:19000/register" in my browser, I get "Cannot GET /register," but I don't get any error when I visit "http://192.168.66.184:19000/"."http://192.168.66.184:19000/" this load on my browser successfully.
Project Structure: Here's the structure of my project for reference:
bloodDonor/
├── api/
│ ├── index.js
│ ├── models/
│ │ ├── donorInfoModel.js
│ │ └── donorRequestModel.js
│ ├── package.json
│ └── package-lock.json
├── App.js
├── app.json
├── ... (other project files)
API Configuration:
I have an API server running in api/index.js
, which listens on port 3000.
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const crypto = require("crypto");
const nodemailer = require("nodemailer");
const app = express();
const port = 3000;
const cors = require("cors");
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const jwt = require("jsonwebtoken");
mongoose
.connect("mongodb+srv://[email protected]/", {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log("Connected to MongoDB");
})
.catch((err) => {
console.log("Error Connecting to MongoDB");
});
app.listen(port, () => {
console.log("server is running on port 3000");
});
const Donor = require('./models/donorInfoModel');
const bloodReqs = require('./models/donorRequestModel');
app.post("/register", async (req, res) => {
try {
const { name, email, password, batch, department, bloodGrp, donationNum, donationDate, mobile, address} = req.body;
const existingUser = await Donor.findOne({ email });
if (existingUser) {
return res.status(400).json({ message: "Email already registered" });
}
//create a new user
const newUser = new Donor({ name, email, password, batch, department, bloodGrp, donationNum, donationDate, mobile, address});
//generate and store the verification token
newUser.verificationToken = crypto.randomBytes(20).toString("hex");
//save the user to the database
await newUser.save();
//send the verification email to the user
sendVerificationEmail(newUser.email, newUser.verificationToken);
res.status(200).json({ message: "Registration successful" });
} catch (error) {
console.log("error registering user", error);
res.status(500).json({ message: "error registering user" });
}
});
const sendVerificationEmail = async (email, verificationToken) => {
//create a nodemailer transporter
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "....",
pass: "....",
},
});
//compose the email message
const mailOptions = {
from: "threads.com",
to: email,
subject: "Email Verification",
text: `please click the following link to verify your email http://10.0.2.2:3000/verify/${verificationToken}`,
};
try {
await transporter.sendMail(mailOptions);
} catch (error) {
console.log("error sending email", error);
}
};
// verification
app.get("/verify/:token", async (req, res) => {
try {
const token = req.params.token;
const user = await User.findOne({ verificationToken: token });
if (!user) {
return res.status(404).json({ message: "Invalid token" });
}
user.verified = true;
user.verificationToken = undefined;
await user.save();
res.status(200).json({ message: "Email verified successfully" });
} catch (error) {
console.log("error getting token", error);
res.status(500).json({ message: "Email verification failed" });
}
});
const generateSecretKey = () => {
const secretKey = crypto.randomBytes(32).toString("hex");
return secretKey;
};
const secretKey = generateSecretKey();
app.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) {
return res.status(404).json({ message: "Invalid email" });
}
if (user.password !== password) {
return res.status(404).json({ message: "Invalid password" });
}
const token = jwt.sign({ userId: user._id }, secretKey);
res.status(200).json({ token });
} catch (error) {
res.status(500).json({ message: "Login failed" });
}
});
My database is connected successfully. $api: npm start
> [email protected] start
> nodemon index.js
[nodemon] 3.0.1
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,cjs,json
[nodemon] starting `node index.js`
server is running on port 3000
Connected to MongoDB
Troubleshooting:
I've also tried using http://localhost:3000/
and also try to use http://localhost:19000/
but the issue remains. I'm running the app on a physical Android device as an emulator and Ubuntu is my operating system.
Question:
How can I resolve this routing issue and successfully make a POST request to the /register
endpoint in my React Native Expo project?