I am working on a MERN stack project for a proof-of-concept and am creating a wall where I can add posts from a form. The form accepts name, tags, title, and a message along with an image. Upon clicking submit, Axios gives me a 404 error in the console.
For example, trying to POST this data (using a mongoose schema):
{creator: 'asdfasddd', title: 'asdfasd', message: 'asdffdd', tags: 'dddd', selectedFile: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0gA…AAAAAAAAAAAAAAAAAYI+9AisfoxArdwtiAAAAAElFTkSuQmCC'}
And I receive this error message:
{message: 'Request failed with status code 404', name: 'AxiosError', code:
'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
This is the AxiosError expanded only once, I can expand the error further if that would help, I've looked through it an found nothing in particular that seems helpful.
[
If somebody could tell me why I am getting this error besides the fact that I am timing out and what would cause me to that would be helpful. One note to help is that I receive some interaction to my DB just no data (of course). My POST functions are here if that helps as well, but I don't believe that is wrong either. If I need to post my the code to my component itself let me know.
import * as api from '../api';
// Action Creators
export const getPosts = () => async (dispatch) => {
try {
const { data } = await api.fetchPosts();
dispatch( {type: 'FETCH_ALL', payload: data });
} catch (error) {
console.log(error.message);
}
}
export const createPost = (post) => async (dispatch) => {
try {
const {data } = await api.createPost(post);
dispatch({type: 'CREATE', payload: data});
} catch (error) {
console.log(post);
console.log(error.toString());
console.log(error);
}
}
Code for POSTS for the back end in my controllers folder.
import PostMessage from '../models/postMessage.js';
export const getPosts = async (req, res) => {
try {
const postMessages = await PostMessage.find();
console.log(postMessages);
res.status(200).json(postMessages);
} catch (error) {
res.status(404).json({ message: error.message});
}
}
export const createPost = async (req, res) => {
const post = req.body;
const newPost = new PostMessage(post);
try {
await newPost.save();
res.status(201).json(newPost);
} catch (error) {
res.status(409).json({ message:error.message});
}
}
Within api folder:
import axios from 'axios';
const url = 'http://localhost:5000/posts';
//const port = process.env.PORT;
//const url = 'http://localhost:3000/posts';
export const fetchPosts = () => axios.get(url);
export const createPost = (newPost) => axios.post(url, newPost);
How the data is routed server-side:
import express from 'express';
import { getPosts, createPost } from '../controllers/posts.js';
const router = express.Router();
//http://localhost:5000/posts
router.get('/', getPosts);
router.get('/', createPost);
export default router;
In your router file, you are missing the POST method
router.post('/', createPost);
In your main file, it should be
app.use("/posts", postRouter)
Related
I used the postman for testing my url,and it has response data(It's correct).
Url:http://localhost:8000/api/products/find/6337d5d73ec2c05d7c11bc63(ProductId).
In postman,it could get response data.
I wonder I do give it Bearer token in my requestMethods.js,which imported in /pages/Product.jsx.
But when I use the same id in axios.get,it said error:
Error:GET http://localhost:8000/api/products/find/6337d5d73ec2c05d7c11bc63 401 (Unauthorized)
can someone just help me solve this question?
In /pages/product.jsx line 145,157 are got tag in the photo.
Here are my relative Codes:
requestMethods.js
import axios from "axios";
const BASE_URL = "http://localhost:8000/api/"
const TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9......"
export const publicRequest = axios.create({
baseURL: BASE_URL,
});
export const userRequest = axios.create({
baseURL: BASE_URL,
headers: { token: `Bearer ${TOKEN}` },
});
/pages/Product.jsx
It's mainly codes of website.
import { useLocation } from 'react-router-dom'
import { useState, useEffect } from 'react';
import { publicRequest,userRequest } from './requestMethods';
const Product = () => {
// 回傳路徑
const location = useLocation();
const id = location.pathname.split("/")[2];
const [product, setProduct] = useState({});
useEffect(() => {
const getProduct = async () => {
try {
const res = await publicRequest.get("/products/find/" + id);//HERE USE REQUESTMETHODS.JS and it's it sad line:145
console.log(res.data)
setProduct(res.data);
}
catch { } }
getProduct();//line 157
}, [id])
}
export default Product
index.js
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const userRouter = require("./routes/user");
const authRouter = require("./routes/auth");
const productRouter = require("./routes/product");
const cors=require("cors");
dotenv.config();
mongoose.connect(
process.env.MONGO_URL)
.then(() => console.log("connect"))
.catch(((err) => {
console.log(err);
}));
app.use(express.json());
app.use(cors());
app.use("/api/users", userRouter);
app.use("/api/auth", authRouter);
app.use("/api/products", productRouter);//USE THE ROUTES/PRODUCT.JS
app.use("/api/orders", orderRouter);
app.use("/api/cart", cartRouter);
app.use("/api/checkout",stripeRouter)
app.listen(process.env.PORT || 8000, () => {
console.log("Run server")
})
routes/product.js
router.put("/:id", verifyTokenAndAdmin, async (req, res) => {
try {
const updatedProduct = await Products.findByIdAndUpdate(req.params.id, {
$set: req.body
}, { new: true }
);
res.status(200).json(updatedProduct);
} catch (err) {
res.status(500).json(err);
}
});
//delete
router.delete("/:id", verifyTokenAndAdmin, async (req, res) => {
try {
await Products.findByIdAndDelete(req.params.id);
res.status(200).json("Products has been deleted.")
} catch (err) {
res.status(500).json(err);
}
})
//get product
router.get("/find/:id", verifyTokenAndAdmin, async (req, res) => {
try {
const product = await Products.findById(req.params.id);
res.status(200).json(product);
} catch (err) {
res.status(500).json(err);
}
})
verifyToken.js
const jwt = require("jsonwebtoken");
const verifyToken = (req, res, next) => {
const authHeader = req.headers.token;
if (authHeader) {
const token = authHeader.split(" ")[1];
jwt.verify(token, process.env.JWT_SEC, (err, user) => {
if (err)
res.status(401).json("Token is not valid!")
req.user = user;
next();
})
}
else {
return res.status(401).json("You are not authentication!" );
}
}
module.exports = { verifyToken, verifyTokenAndAuth, verifyTokenAndAdmin };
The reason is you are using publicRequest axios function which does not include bearer token header. Use userRequest function.
Try using the code below in your axios request from frontend:
const res = await userRequest.get("/products/find/${id}");
Instead of double quotes use string literal. Stack overflow is using my string literal as code snippet that's why I wrote in double quotes.
Also remove the extra slash after api from BASE_URL like this:
const BASE_URL = "http://localhost:8000/api"
Also check in your verifyToken.js file if you have written the functions verifyTokenAndAuth and verifyTokenAndAdmin which you are exporting. If not then please write those functions in verifyToken.js file and then export because you are using verifyTokenAndAdmin middleware in your api. Also please check that server is running and not crashing before making a request.
I will just say first of all that I am aware of almost all the questions asked on this site under this title.
The solutions there were pretty obvious and already done by me (with no success) or only helped for those specific cases and didn’t really work in my case unfortunately.
Now, for the problem:
I'm trying to create a route that will handle a get request and a post request which are sent to the route 'ellipses'.
These requests should receive and send data from and to an SQL database.
The problem is that for some reason the router is not ready to get these functions and gives me the error in the title:
Router.use () requires middleware function but got an undefined
Here is my code:
This code is from the file dat.js. its porpose is just to access the SQL database.
import { Sequelize } from "sequelize";
export const sequelize = new Sequelize('TheDataBaseName', 'TheUser', 'ThePassword', {
host: 'localhost',
dialect: 'mssql'
});
This code is from the file: controller.js. its porpose is to manage the requests and load the data.
import { sequelize } from "../dat";
export const sendEllipses = async (req, res, next) => {
try {
const ellipses = await getEllipsesFromJson();
return res.send(ellipses);
} catch (e) {
console.log(e);
}
};
export const addNewEllipse = async (req, res, next) => {
const { body: obj } = req;
let newEllipse;
try {
if (Object.keys(obj) !== null) {
logger.info(obj);
newEllipse = await sequelize.query(
`INSERT INTO [armageddon].[dbo].[ellipses] (${Object.keys(
obj
).toString()})
values (${Object.values(obj).toString()})`
);
} else {
console.log("the values are null or are empty");
}
return res.send(newEllipse);
} catch (error) {
console.log(error);
}
};
This code is on the file: routers.js.
its porpose is to define the route
import Router from "express";
import { sendEllipses } from "../ellipses.controller";
import { addNewEllipse } from "../ellipses.controller";
const router = Router();
export default router.route("/ellipses").get(sendEllipses).post(addNewEllipse);
This code is from the file: app.js. This is where everything actually happens.
import { router } from "../routers";
import express from "express";
app.use('/api', router);
app.listen(5000, () => {
console.log("server is runing on port 5000")
});
You need to export the router
const router = Router();
router.route("/ellipses").get(sendEllipses).post(addNewEllipse)
export default router
Now import the router:
import routes from "../router.js";
app.use('/api', routes);
Its also mentioned in the docs: https://expressjs.com/de/guide/routing.html#express-router
I can't reach server side I checked everything it should work
error is:
"POST http://localhost:3000/ 404 (Not Found)"
Here is my code
On client side here, I call createPost at jsx file and in actions/post.js file:
import * as api from "../api/index";
import * as types from "./types";
export const createPost = (post) => async (dispatch) =>{
try {
const {data} = await api.createPost(post);
dispatch({
type: types.CREATE_POST,
payload: data,
});
} catch (error) {
console.log(error);
}
};
from here it should call the api,
import axios from "axios";
const apiEndpoint = "/";
export const fetchPosts = async () => await axios.get(apiEndpoint);
export const createPost = async (post) => await axios.post(apiEndpoint, post);
and from there to server side but there is a error at createPost first.
btw in server,
import express from "express";
import {getPosts, createPost} from "../contollers/posts.js";
const router = express.Router();
//localhost/posts
// GET POST DELETE UPDATE
router.get("/", getPosts);
router.post("/", createPost);
export default router;
and in controller:
export const createPost = async(req,res) => {
const post = req.body;
const newPost = new Post(req.body);
try{
await newPost.save();
res.status(201).json(newPost);
}catch(error){
res.status(409).json({
message: error.message,
});
}
};
thanks for help
yeah its my stupidity that correcting some router&dom versions and url to 5000(which is the server) solved the issue
I'm trying to create a routing function for some products. The home screen works fine (displaying all the products), but I'm trying to add functionality so that when a user clicks on the product it automatically redirects to a page which pulls information about that products.
When I run my back end server (npm start) I get this in my terminal and an undefined response when I click on my product:
[nodemon] 2.0.12
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): backend/**/*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `babel-node backend/server.js`
serve at http://localhost:5000 [Function (anonymous)]
I've tried going through my code a few times and playing around with things to see if there's an issue with a function but couldn't see an issue.
This is the code for my server.js:
import express from 'express';
import cors from 'cors';
import { products } from './data.js';
const app = express();
app.use(cors());
app.get('/api/products', (_req, res) => {
res.send(products);
});
app.get('/api/products/:id')
app.listen(5000, () => {
console.log('serve at http://localhost:5000', (req, res) => {
const product = data.products.find((x) => x._id === req.params.id)
if (product) {
res.send(product);
} else {
res.status(404).send({ message: 'Product Not Found' })
}
})
});
This is my config.js:
import axios from 'axios'
import { apiUrl } from "./config"
export const getProduct = async (id) => {
try {
const response = await axios({
url: `${apiUrl}/api/products/${id}`,
method: 'GET',
headers: {
'Content-Type': 'application/json',
}
});
if (response.statusText !== 'OK') {
throw new Error(response.data.message);
}
return response.data;
} catch (err) {
console.log(err);
return { error: err.message }
}
};
I've just included my util.js and the product screen code below just for a better understanding of what I'm doing, however I think the issue would be in the server.js or config.js.
util.js:
export const parseRequestUrl = () => {
const url = document.location.hash.toLowerCase();
const request = url.split('/');
return {
resource: request[1],
id: request[2],
action: [3],
};
}
productscreen.js
import { getProduct } from '../api';
import { parseRequestUrl } from '../util'
const ProductScreen = {
render: async () => {
const request = parseRequestUrl();
const product = await getProduct(request.id);
return `<h1>${product.name}</h1>`;
}
}
export default ProductScreen;
You are literally printing the function with console.log by providing it as a second argument. Move the handler function to the appropriate route handler for /api/products/:id, as shown below:
import express from 'express';
import cors from 'cors';
import { products } from './data.js';
const app = express();
app.use(cors());
app.get('/api/products', (_req, res) => {
res.send(products);
});
// The handler function is moved here from `listen` callback.
app.get('/api/products/:id', (req, res) => {
const product = data.products.find((x) => x._id === req.params.id);
if (product) {
res.send(product);
} else {
res.status(404).send({ message: 'Product Not Found' });
}
})
app.listen(5000, () => {
console.log('serve at http://localhost:5000');
});
I am building a register page and when I submit the I am getting a 404 not found. I am using react and express and I think the front end is good. I am missing some back end or have the wrong url for my post request: axios.post('http://localhost:3000/auth'. Would appreciate some advice if anyone can see what I have wrong.
const handleSubmit = event => {
event.preventDefault();
const user = {
username: username,
password: password,
}
axios.post('http://localhost:5000/', { user })
.then(res=>{
console.log(res);
console.log(res.data);
})
}
This is the registerPost function for my route.
export const registerPost = async (req, res) => {
const {username, password} = req.body;
const newUser = new User({username, password});
try {
await newUser.save();
console.log(newUser);
res.status(201).json(newUser);
} catch (error) {
res.status(409).json({ message: error.message });
}
}
These are the routes.
import express from 'express';
import { getPosts } from '../controllers/posts.js'
import { createPost, updatePost, deletePost, registerPost } from '../controllers/posts.js'
const router = express.Router();
router.get('/', getPosts);
router.post('/', createPost);
router.patch('/:id', updatePost);
router.delete('/:id', deletePost);
router.post('/auth', registerPost);
export default router;
You're getting a 404 error, which means the url you're trying to reach does not exist. In the React app, you're sending the request at http://localhost:5000/, but in the Express app, you've defined the register route as /auth.
Updating the url in the React app to http://localhost:5000/auth should fix this.
As far as I can see you're passing the following Object from the Frontend:
{ user: { username, password } }
but in the backend you're not looking for the user property, but directly for the username and password.
const {username, password} = req.body
// =>
const { user } = req.body