Express.js - can find my route - reactjs

I'm using react.js and express.js and getting 404 error on my fetch request.
I'm simply trying to have my routes return testing express.js...
[app.js]
'use strict';
const NODE_ENV = process.env.NODE_ENV;
const PORT = process.env.PORT;
const next = require('next');
const express = require('express');
const api = require('./api');
const client = next({ dev: NODE_ENV === 'development' });
const clientHandler = client.getRequestHandler();
const app = express();
client.prepare().then(() => {
app.use('/api', api);
app.get('*', (req, res) => clientHandler(req, res));
});
const listener = app.listen(PORT, err => {
if (err) throw err;
console.log('listening on port: %d', listener.address().port); //eslint-disable-line
});
[/api/index.js]
'use strict';
const express = require('express');
const app = express();
app.get('/api/test', function (req, res) {
res.send('testing express.js...');
});
module.exports = app;
[Body.js]
import React from 'react';
export default class Body extends React.Component {
constructor(props) {
super(props);
this.fetchContacts = this.fetchContacts.bind(this);
}
componentDidMount() {
this.fetchContacts();
}
async fetchContacts() {
const res = await fetch('/api/test');
const contacts = await res.json();
log(contacts);
this.setState({ contacts });
}
render() {
return <div>hello world!</div>;
}
}
Question: Why am I getting a 404 error?

To make your /api/test route work properly, you need to change this:
app.get('/api/test', function (req, res) {
res.send('testing express.js...');
});
to this:
app.get('/test', function (req, res) {
res.send('testing express.js...');
});
Your router is already looking at /api so when you then put a route on the router for /api/test, you were actually making a route for /api/api/test. To fix it, make the above change.
Also, your index.js file should not be using an app object. It should be using an express.Router() object, though an app object is also a router so it might kind of work, but it's not the way it should be done.

That is not the way to load a react JS file on nodejs, follow this basic (React + NodeJS) guide:
https://blog.yld.io/2015/06/10/getting-started-with-react-and-node-js/#.Wd7zSBiWbyg
Or use "create-react-app" :
https://medium.com/#patriciolpezjuri/using-create-react-app-with-react-router-express-js-8fa658bf892d

Related

unexpected token in json at position 0 reactjs mongodb

///component
function Home() {
const [show, setShow]= useState([{name:'', info:'', airingDate:'', poster:''}])
useEffect(()=>{
fetch("/home")
//.then(res=> res.json())
.then(res => res.text())
.then(text => console.log(text))
})
return (
<div>
{show.map(a=>
<div>
<h2>{a.title}</h2>
</div>
)}
</div>
)
/////index.js
const TvShows = require("./models/TvShows");
const express = require("express");
const app = express();
const mongoose= require("mongoose")
const dotenv= require("dotenv");
const authRoute = require("./routes/auth");
const { application } = require("express");
const userRoute = require("./routes/users");
const commentRoute = require("./routes/comments");
const tvshowsRoute = require("./routes/tvshows");
const cors = require("cors");
app.use(cors());
console.log(".");
dotenv.config();
app.use(express.json());
mongoose.connect(process.env.MONGO_URL,{
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
}).then(console.log("connected to mongoDB"));
app.use("/auth", authRoute);
app.use("/users", userRoute);
app.use("/comments", commentRoute);
app.post("/api/home", tvshowsRoute);
app.use("/api/home", tvshowsRoute);
/*
app.get('/api/home', (req,res)=>{
TvShows.find().then((result)=>{
res.send(result);
})
})
*/
/*
app.use("/",(req,res)=>{
console.log("main url")
})*/
app.listen("3001",()=>{
console.log("backend running");
})
//////route
const router = require("express").Router();
const TvShows = require("../models/TvShows");
router.post("/api/home", async (req, res) => {
console.log("here")
try{
const newTvShow = new TvShows({
title: req.body.title,
poster: req.body.poster,
info: req.body.info
});
const savedTvShows = await newTvShow.save();
res.status(200).json(savedTvShows);
}catch (err) {
res.status(500).json(err);
}
}
);
router.route("/api/home").get((req, res)=>{
TvShows.find()
.then(foundShows=> res.json(foundShows))
})
module.exports = router;
when I change res.json with res.text I see my index.html page on console not the data I want to fetch from mongodb. This error is probably because I didn't use /api/ on root url but I couldn't figure it out where I should write it. I tried but didn't work. It would be so good if someone could've helped. Thank you so much.
Indeed, you are fetching the /home page of your front-end app.
Assuming the api is on a different server, you would need to call the address of that server.
If you have a set up locally with a nodejs server and a react app running separately, you should have them run on two different ports.
If you have react app on http://localhost:3000 (default), then change your api to listen on 3001, then in your react code above, you can use the full uri
http://localhost:3001/api/home
in your fetch call.
I'm making a lot of assumptions about how you have this set up, based on my own experience of local development for similar problems.

NextJs - React component methods get called twice per request

I'm experimenting with NextJs Custom Server using Express. And i noticed that on every request, getInitialProps gets called twice. When trying to find out what the problem is i stumbled upon React.Strictmode being the reason for that since it calls certain class methods and constructor twice to help debug. When setting it to false, the getInitialProps method gets called three times. NextJs "pages" folder routing is disabled.
To be mentioned that render() gets called twice or three times too.
My server.js :
require('dotenv').config();
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const mongoose = require('mongoose');
const app = next({ dev });
mongoose.connect(process.env.DB_URI)
.then(()=>{
console.log('>Succesfully connected to the database');
app.prepare()
.then(() => {
const server = express();
server.listen(3000, (req, res) =>{
console.log('>Listening on port 3000');
});
server.get('*', (req, res)=>{
app.render(req, res, '/index', {something:true});
})
})
.catch((ex) => {
console.error(ex.stack);
process.exit(1);
})
})
.catch(e=>{
console.log('<!>Error connecting to database: \n' + e);
});
and my GetInitialProps:
static async getInitialProps(ctx){
console.log({...ctx.query});
console.log('once');
return {props:{...ctx.query}};
}
Console when Strictmode on:
{ something: true }
once
{ something: true }
once
Console when Strictmode off:
{ something: true }
once
{ something: true }
once
{ something: true }
once

change code from template engine to next js

How do I convert my app that is made with .pug to next app ? I have an app using .pug engine and I want to convert it into next.
This is the app.js but as I know next is different how do I do it? Because here my files are in views, and in views the files are in pages etc how do I do it? Is there any way or I have to code it all again?
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
const middleware = require('./middleware')
const path = require('path')
const bodyParser = require("body-parser")
const mongoose = require("./database");
const session = require("express-session");
const http = require('http');
const server = app.listen(port, () => console.log("Server listening on port " + port));
const io = require("socket.io")(server, { pingTimeout: 60000 });
app.set("view engine", "pug");
app.set("views", "views");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, "public")));
app.use(session({
secret: "#########",
resave: true,
saveUninitialized: false
}))
// Routes
const loginRoute = require('./routes/loginRoutes');
const registerRoute = require('./routes/registerRoutes');
const logoutRoute = require('./routes/logout');
const postRoute = require('./routes/postRoutes');
const profileRoute = require('./routes/profileRoutes');
const uploadRoute = require('./routes/uploadRoutes');
const searchRoute = require('./routes/searchRoutes');
const messagesRoute = require('./routes/messagesRoutes');
const notificationsRoute = require('./routes/notificationRoutes');
// Api routes
const postsApiRoute = require('./routes/api/posts');
const usersApiRoute = require('./routes/api/users');
const chatsApiRoute = require('./routes/api/chats');
const messagesApiRoute = require('./routes/api/messages');
const notificationsApiRoute = require('./routes/api/notifications');
app.use("/login", loginRoute);
app.use("/register", registerRoute);
app.use("/logout", logoutRoute);
app.use("/posts", middleware.requireLogin, postRoute);
app.use("/profile", middleware.requireLogin, profileRoute);
app.use("/uploads", uploadRoute);
app.use("/search", middleware.requireLogin, searchRoute);
app.use("/messages", middleware.requireLogin, messagesRoute);
app.use("/notifications", middleware.requireLogin, notificationsRoute);
app.use("/api/posts", postsApiRoute);
app.use("/api/users", usersApiRoute);
app.use("/api/chats", chatsApiRoute);
app.use("/api/messages", messagesApiRoute);
app.use("/api/notifications", notificationsApiRoute);
app.get("/", middleware.requireLogin, (req, res, next) => {
var payload = {
pageTitle: "Home",
userLoggedIn: req.session.user,
userLoggedInJs: JSON.stringify(req.session.user),
}
res.status(200).render("home", payload);
})
io.on("connection", socket => {
socket.on("setup", userData => {
socket.join(userData._id);
socket.emit("connected");
})
socket.on("join room", room => socket.join(room));
socket.on("typing", room => socket.in(room).emit("typing"));
socket.on("stop typing", room => socket.in(room).emit("stop typing"));
socket.on("notification received", room => socket.in(room).emit("notification received"));
socket.on("new message", newMessage => {
var chat = newMessage.chat;
if(!chat.users) return console.log("Chat.users not defined");
chat.users.forEach(user => {
if(user._id == newMessage.sender._id) return;
socket.in(user._id).emit("message received", newMessage);
})
});
})
If you don't want to refactor all your pug template engine pages to next.js pages, then you can make the pug pages coexist with the next.js. You can make the next.js the default route, and place next.js code after all pug page routes. And you also need to refactor app.get("/", middleware.requireLogin, (req, res, next) => {...} to make sure next.js is the default route.
To apply this rule, you need a custom next.js server.
sample code
const express = require('express');
const next = require('next');
const port = 3000;
const dev = process.env.NODE_ENV !== 'production'; // use default NodeJS environment variable to figure out dev mode
const app = next({dev, conf});
const handle = app.getRequestHandler();
const server = express();
// all your pug page routes should be declared before `server.get('*'`.
server.get('*', authMiddleware(false), (req, res) => {
// pass through everything to NextJS
return handle(req, res);
});
app.prepare().then(() => {
server.listen(port, (err) => {
if (err) throw err;
console.log('NextJS is ready on http://localhost:' + port);
});
}).catch(e => {
console.error(e.stack);
process.exit(1);
});

Mongoose TypeError: TypeError: Cannot use 'in' operator to search for 'pluralization' in undefined

Not really sure what's going on here. I see that others have encountered this error before, but I guess I just don't understand enough to draw parallels between what they were doing wrong and what I'm doing wrong.
This is just a simple project to learn the MERN stack. The objective here is relatively simple: upload a PDF file to a mongoDB database, retrieve that PDF file, and display it to a preview window. Possibly an iframe, or something simpler, depending on the options available to me. At the moment, my primary issue is with the back end.
So, here is my code:
index.js (username and password omitted, of course):
import express from 'express';
import mongoose from 'mongoose';
import bodyParser from 'body-parser';
import cors from 'cors';
import { router } from './routes/image-route.js';
const app = express();
const port = 5000;
app.use(bodyParser.json({limit: "20mb", extended: true}));
app.use(bodyParser.urlencoded({limit: "20mb", extended: true}));
app.use('./routes/image-route.js', router)
app.use(cors());
const CONNECTION_URL = 'mongodb+srv://<username>:<password>#cluster0.xxpzv.mongodb.net/myFirstDatabase?retryWrites=true&w=majority';
async function main() {
await mongoose.connect(CONNECTION_URL).then(() => console.log("SERVER CONNECTION ESTABLISHED"));
}
main().catch(err => console.log(err));
app.listen(port, () => console.log(`listening at port ${port}`));
image_model.js:
import mongoose from 'mongoose';
const imageSchema = mongoose.Schema({
name: String,
img:
{
data: Buffer,
contentType: String
}
});
const imageData = mongoose.model('image', 'imageSchema')
export { imageData };
image-route.js:
import express from 'express';
import { getImage, postImage } from '../controllers/image_controller.js';
const router = express.Router();
router.get('/', getImage);
router.post('/', postImage);
export { router };
image_controller.js:
import { imageData } from '../models/image_model.js';
export const getImage = async (req, res) => {
try {
const allImages = await imageData.find();
req.status(200).json(allImages);
console.log('Successfully submitted');
} catch (err) {
res.status(404).json({message: error.message});
}
}
export const postImage = async (req, res) => {
const image = req.body;
const newImage = new imageData(image);
try {
await newImage.save();
res.status(201).json(newImage);
} catch (error) {
res.status(409).json({message: error.message});
}
}
And this is the error I'm receiving when I attempt to start the server:
I'm not really sure what else to say. I've tried the solutions I've seen for similar problems (to the best of my understanding), but their problems were apparently not quite the same as mine. If there's anything else anyone needs to know to help me with this, I'll provide whatever is necessary. Thanks in advance.
file: image_model.js
const imageData = mongoose.model('image', 'imageSchema')
// imageSchema is not a string
change to:
const imageData = mongoose.model('image', imageSchema)

Issues getting an Express resonse from locally hosted MongoDB (Node.js)

I am trying to pass data from my locally hosted MongoDB collection to the front end of my app for testing purposes.
I am running into trouble trying to get my front end talking to my backend.
I've tried changing the params around in my "getData" route... and I think I am a little turned around.
const mongoose = require("mongoose");
const express = require("express");
var cors = require("cors");
const bodyParser = require("body-parser");
const logger = require("morgan");
const API_PORT = 27017;
const app = express();
app.use(cors());
const router = express.Router();
const dbRoute = "mongodb://127.0.0.1:27017/nycsandy";
mongoose.connect(
dbRoute,
{ useNewUrlParser: true }
);
let db = mongoose.connection;
let dbdata;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
db.db.collection("socialmedia", function(err, collection){
collection.find({}).toArray(function(err, data){
console.log("data length from coll ", data.length); // it will print the collection data just fine
dbdata = data
})
});
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(logger("dev"));
// I need to get this to just return data
router.get("/getData", (req, res) => {
return dbdata
// I don't know what to put here to get my response?
});
.....
The front end App.js looks like :
// /client/App.js
import React, { Component } from "react";
import axios from "axios";
class App extends Component {
// initialize our state
state = {
data: [],
id: 0,
message: null,
intervalIsSet: false,
idToDelete: null,
idToUpdate: null,
objectToUpdate: null
};
componentDidMount() {
this.getDataFromDb();
if (!this.state.intervalIsSet) {
let interval = setInterval(this.getDataFromDb, 10000);
this.setState({ intervalIsSet: interval });
}
}
componentWillUnmount() {
if (this.state.intervalIsSet) {
clearInterval(this.state.intervalIsSet);
this.setState({ intervalIsSet: null });
}
}
getDataFromDb = () => {
fetch("http://localhost:27017/api/getData")
.then(data => data.text())
.then(text => console.log(text))
// just testing it for now.
};
......
This throws an empty response error. ERR_EMPTY_RESPONSE
I'm just a little lost on how I get my data, which does log to the console correctly, into my getData route.
Thanks.
In your router.get try this:
res.status(200).send("whatYouWantToSend")

Resources