unexpected token in json at position 0 reactjs mongodb - reactjs

///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.

Related

Error while Inserting Data through Thunderclient into MONGODB

I'm new in using MERN Stack & I'm trying to connect Mongo and Node but facing this issue while inserting Data into Database, using MongoDb Compass
Index.js
const connectToMongo = require('./db');
const express = require('express')
connectToMongo();
const app = express()
const port = 3000
app.use(express.json())
//Available Routes
app.use('/api/auth', require('./routes/auth'))
app.use('/api/auth', require('./routes/notes'))
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
User.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const UserSchema = new Schema({
name:{
type: String,
require: true
},
email:{
type:String,
require:true,
unique: true
},
password:{
type:String,
require:true
},
timestamp:{
type:Date,
default:Date.now
}
});
module.exports = mongoose.model('user', UserSchema)
auth.js
const express=require('express');
const User = require('../models/User');
const router=express.Router()
router.get('/', (req, res)=>{
console.log(req.body)
const user = User(req.body)
user.save()
res.send(req.body)
})
module.exports = router
db.js
const mongoose = require('mongoose')
const mongoURI = "mongodb://localhost:27017/"
const connectToMongo=()=>{
mongoose.set("strictQuery", false);
mongoose.connect(mongoURI,()=>{
console.log("Connected to Mongo Successfully")
})
}
module.exports = connectToMongo;
ThunderClient Request:
{
"name":"pratik",
"email":"pratik#mail.com",
"password":"6626"
}
Error:
const err = new MongooseError(message);
^
MongooseError: Operation users.insertOne() buffering timed out after 10000ms
at Timeout. (D:\Study\React\MERN\inotebook\backend\node_modules\mongoose\lib\drivers\node-mongodb-native\collection.js:175:23)
at listOnTimeout (node:internal/timers:564:17)
at process.processTimers (node:internal/timers:507:7)
I guess the problem is because of the newer version, I'm trying to read the Docs and StackOverFlow but unable to Solve this Error what should I Do
You get the error because you are not connected to mongo actually.
You miss async/await in db.js
const connectToMongo = async () => {
mongoose.set("strictQuery", false);
await mongoose.connect(mongoURI,
// you can add this opts
{ keepAlive: true,
useNewUrlParser: true,
useUnifiedTopology: true,
})
console.log("Connected to Mongo Successfully")
}
And also later when you are calling user.save() it also should be async:
async (req, res)=>{
console.log(req.body)
const user = User(req.body)
await user.save()
res.send(req.body)
Thanks Everyone
the Solution was quite simple,
Just Change your localhost to 127.0.0.1:270

How to resolve the Socket.io error "ERR_NAME_NOT_RESOLVED

When I run my MERN Stack project on my localhost and get my app's render page, when I click on a button in my app, that button does and displays nothing. When I inspect my client-side render page, I see the following error:polling.js:311 GET http://%22http/socket.io/?EIO=4&transport=polling&t=O7Mtvxd net::ERR_NAME_NOT_RESOLVED. I don't know what it means, I searched the meaning on the internet but without success. Here is my backend index.js file:
const express = require('express')
const cors = require('cors')
const mongoose = require('mongoose')
require("dotenv").config()
const app = express()
const http = require('http')
const server = http.createServer(app)
const io = require('socket.io')(server)
const UserRoutes = require('./routes/User')
const AuthRoutes = require('./routes/Auth')
const PostRoutes = require('./routes/Post')
const PORT = process.env.PORT || 5000
const {MONGODB_URI} = require("./config")
app.use(cors())
app.use(express.json())
app.use((req, res, next) => {
io.req = req
req.io = io
next()
})
app.use('/api/auth', AuthRoutes)
app.use('/api/user', UserRoutes)
app.use('/api/post', PostRoutes)
require('./socket')(io)
mongoose
.connect(MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then(() => {
console.log('database connected')
server.listen(PORT, () => console.log(`server started on port ${PORT}`))
})
.catch((err) => console.log(err))
my backend socket.js file :
const User = require('./models/User')
const jwt = require('jsonwebtoken')
module.exports = (io) => {
io.on('connection', (socket) => {
if (io.req) {
socket.broadcast.emit('friend-login-status', { user_id: io.req.userId })
addSocketIdInDB(socket.id, io.req.userId)
socket.on('disconnect', () => {
socket.broadcast.emit('friend-logout-status', {
user_id: io.req.userId,
})
io.req.userId = null
})
}
})
}
async function addSocketIdInDB(socket_id, user_id) {
const user = await User.findById(user_id)
if (socket_id) {
user.socketId = socket_id
}
await user.save()
}
I looked on this question after this but without success. I work on Microsoft Edge .

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);
});

How to Get Param Id from URL in express/mongo/mongoose on server side, axios/react/redux on client side

I am having some trouble with get the param from the url. I use Express(4.16.3) on the server side, and using Axios to make the request. But I couldn't seem to get the param from the url in Express.
Here is my code:
on my Route.js in Express
app.get('/api/surveys/:surveyId', (req, res, next) => {
var id = req.params.surveyId;
console.log(req.params);
// it gets params {surveyId: ':surverId'}
res.send('Hello World');
});
so instead of getting the actual id, it logs params: {surveyId: ':surveyId'}. I have been researching, but seems this is the correct way to do it. I also use axios to make the request:
in actions/index.js (I use react):
export const fetchOneSurvey = () => async dispatch => {
const res = await axios.get('/api/surveys/:surveyId');
dispatch({ type: FETCH_ONE_SURVEY, payload: res.data });};
Not sure if this is relevant:
On the view page, instead of having http://localhost:3000/api/surveys/:surveyId, I have http://localhost:3000/surveys/:surveyId route set in React. When I go to http://localhost:3000/surveys/:surveyId, it does console log (req.params) like I write in express, but I only get a string ':surveyId' is the params, not the actual id on the url.
Please anyone can help me? I have tried many different ways, but nothing seem working. I thank you all very much in advance.
===== Extra section ======
Here is my index.js:
const express = require('express');
const mongoose = require('mongoose');
const cookieSession = require('cookie-session');
const passport = require('passport');
const bodyParser = require('body-parser');
const keys = require('./config/keys');
require('./models/User');
require('./models/Survey');
require('./services/passport');
mongoose.connect(keys.mongoURI);
const app = express();
app.use(bodyParser.json());
app.use(
cookieSession({
maxAge: 30 * 24 * 60 * 60 * 1000,
keys: [keys.cookieKey]
})
);
app.use(passport.initialize());
app.use(passport.session());
require('./routes/authRoutes')(app);
require('./routes/billingRoutes')(app);
require('./routes/surveyRoutes')(app);
if (process.env.NODE_ENV === 'production') {
app.use(express.static('client/build'));
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
My survey model route js:
const _ = require('lodash');
const Path = require('path-parser');
const { URL } = require('url');
const mongoose = require('mongoose');
const requireLogin = require('../middlewares/requireLogin');
const requireCredits = require('../middlewares/requireCredits');
const Mailer = require('../services/Mailer');
const surveyTemplate = require('../services/emailTemplates/surveyTemplate');
const Survey = mongoose.model('surveys');
module.exports = app => {
app.get('/api/surveys', requireLogin, async (req, res) => {
const surveys = await Survey.find({ _user: req.user.id }).select({
recipients: false
});
res.send(surveys);
});
app.get('/api/surveys/:surveyId/:choice', (req, res) => {
res.send('thanks for voting');
});
app.get('/api/surveys/:surveyId', (req, res, next) => {
var id = req.params.surveyId;
console.log(id);
// it gets params {surveyId: ':surverId'}
res.send('Hello World');
});
app.post('/api/surveys/webhooks', (req, res) => {
// console.log(req.body);
// res.send({});
const p = new Path('/api/surveys/:surveyId/:choice');
const test = _.chain(req.body)
.map(({ email, url }) => {
const match = p.test(new URL(url).pathname);
if (match) {
return {
email,
surveyId: match.surveyId,
choice: match.choice
};
}
})
.compact()
.uniqBy('email', 'surveyId')
.each(({ surveyId, email, choice }) => {
Survey.updateOne(
{
// have to add _ to keys as mongoDB rule, mongoose doensn't need.
_id: surveyId,
recipients: {
$elemMatch: { email: email, responded: false }
}
},
{
$inc: { [choice]: 1 },
$set: { 'recipients.$.responded': true },
lastResponded: new Date()
}
).exec();
})
.value();
console.log(test);
res.send({});
});
app.post('/api/surveys', requireLogin, requireCredits, async (req, res) => {
const { title, subject, body, recipients } = req.body;
const survey = new Survey({
// map(email => ({ email }) === map(email =>{ return {email: email}})
title,
body,
subject,
recipients: recipients
.split(',')
.map(email => ({ email: email.trim() })),
_user: req.user.id,
dateSent: Date.now()
});
// send an email
const mailer = new Mailer(survey, surveyTemplate(survey));
try {
await mailer.send();
await survey.save();
req.user.credits -= 1;
const user = await req.user.save();
res.send(user);
} catch (err) {
res.status(422).send(err);
}
});
};
Posting below details for debugging the issue
Note: if you are using Windows OS, use command prompt for node project development. i have seen people using git bash for doing node project developments and it causes unnecessary issues
Below are the steps for debugging
1.Create a new directoryforexample test and initialize it using npm init
2.Install express npm install --save express
3.Create a new file for example index.js and use below code
test/index.js
var express= require("express");
var app = express();
app.get("/api/surveys/:surveyId",(req,res,next)=>{
console.log(req.params.surveyId);
res.send('Hello World');
});
var server= app.listen(3000,()=>{
console.log("port started at ",server.address().port);
})
4.Start the program node index.js
5.Trigger http request from browser http://localhost:3000/api/surveys/llads . The value llads can be accessed using the path param surveyId in the route
6.if you can see the below output in node console then the program is working as it should. And this has to work as described here.
if above steps yields expected output then i don't see any problem in your route code.
Let me know your feedback.

Express.js - can find my route

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

Resources