I am following a tutorial in order to understand how to connect the express routes that I have written to a react app.
The code, as I best understand it, is supposed to work as follows
App.js
import axios from "axios"
import React, { useState } from "react"
import "./App.css"
function App() {
const [ name, setName ] = useState("")
const [ home, setHome ] = useState("")
useEffect(() => {
axios.get("http://localhost:4000/home").then(function(response) {
setHome(response.data)
})
}, [])
async function postName(e) {
e.preventDefault()
try {
await axios.post("http://localhost:4000/post_name", {
name
})
} catch (error) {
console.error(error)
}
}
return (
<div className="App">
<form onSubmit={postName}>
<input type="text" value={name} onChange={(e) => setName(e.target.value)} />
<button type="submit">Send Name</button>
</form>
{home}
</div>
)
}
export default App
the body above has a submit form that takes text inputted by the user, then on submit the form calls the async function postName. postName utilizes the built in function axios.post which fetches the url corresponding to the url/express_route my index.js is using and passes in the object name which I created at the top of the function in my useState.
In the index.js
const express = require("express")
const app = express()
const port = 4000
const cors = require("cors")
// npm init
// npm i express cors nodemon
// they add a handy req.body object to our req,
// containing a Javascript
// object representing the payload sent with the request
app.use(express.urlencoded({ extended: true }))
app.use(express.json())
app.use(cors())
app.get("/", cors(), async (req, res) => {
res.send("This is working")
})
app.get("/home", cors(), async (req, res) => {
res.send("This is the data for the home page")
})
app.post("/post_name", async (req, res) => {
let { name } = req.body
console.log(name)
})
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}`)
})
we have an async function app.post which is meant to deal with the express route we set up in the axios function and then prints the submitted name to console. I am able to get both of them running. I have nodemon, express axios and cors installed to allow for communication between the different urls. What am I missing why is this happening.
Related
Im encountering this error on replit while setting up my express server, im still starting to learn express so i still dont know some of it means
/home/runner/log-in-API/node_modules/express/lib/router/index.js:513
this.stack.push(layer);
^
TypeError: Cannot read properties of undefined (reading 'push')
at Function.route (/home/runner/log-in-API/node_modules/express/lib/router/index.js:513:14)
at file:///home/runner/log-in-API/api/reviews.route.js:4:8
at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
here is my index.js
import app from "./server.js"
import mongodb from "mongodb"
/* import ReviewsDao from "./dao/reviewsDAO.js " */
const dbUser = process.env['MONGO_USERNAME']
const dbPword = process.env['MONGO_PASSWORD']
const MongoClient = mongodb.MongoClient
const uri = `SECRET`
const port = 8000
MongoClient.connect(uri, {
maxPoolSize: 50,
wtimeoutMS: 2500,
useNewUrlParser: true
})
.catch(err => {
console.error(err.stack)
process.exit(1)
})
.then(async client => {
await ReviewsDAO.injectDB(client)
app.listen(port, () => {
console.log(`Listening to ${port}`)
})
})
here is my server.js
import express from "express"
import cors from "cors"
import reviews from "./api/reviews.route.js"
const app = express()
app.use(cors())
app.use(express.json())
app.use("/api/v1/reviews", reviews)
app.use("*", (req, res) => res.status(404).json({error: "not found"}))
export default app
and here is my reviews.route.js that is located inside a folder named api
import express from 'express'
const router = express.Router
router.route('/').get((req, res) => {
res.send('Hello world')
})
export default router
Am i missing something im trying to follow this tutorial by free code camp and im currently at 6:16:30 timestamp
i tried to fix everything even typos, and im still encountering this problem what could be the problem ?
I think this problem is created because the way you structure your router, try router.get('/', (req, res) => { instead of router.route('/').get((req, res) => {. Does this work? And to initialise your router try const router = express.Router(); instead of const router = express.Router (so call the factory function)
I am trying to set up a few pages so that when a user goes to locahost:number/war . They can see the /war page. But when I run the server I get a "Cannot GET war" error on the page. I've set it up similar to this before and didnt have an issue.
I also get a "ReferenceError: __dirname is not defined" issue on the console
import express from 'express';
const app = express();
const router = express.Router();
import path from 'path';
import {getData} from './server.js'
// HTML Routes
router.get('/', (req,res)=> {
res.sendFile(path.join(__dirname, "../start.html"));
})
router.get('/war', (req,res)=> {
res.sendFile(path.join(__dirname, "../index.html"));
})
router.get('/score', (req,res)=> {
res.sendFile(path.join(__dirname, "../finalScore.html"));
})
// Data
export async function sendStats(){
app.get("/data", (req,res)=> {
const data = getData()
res.json(data)
})
app.post("/data",(req, res) => {
const {name, score} = req.body
const data = createData(name, score)
res.json(data)
} )
app.use((err, req, res, next) => {
console.log(err.stack)
res.status(500).send('Something Broke!')
})
app.listen(7171, ()=> {
console.log('Server is running on port 9191')
})
}
const data = await sendStats();
You forgot to load the router in the app:
app.use('/', router)
hey I'm very new to MERN stack and I'm having an issue posting data with Axios and express. I might have understood this wrong but here goes my problem. I have a form on a page which I'm trying to submit data from to the backend where I then console log it. the page is a component which contains the onsubmit function, which sends a post request to server.js which then console.logs it, however I've been getting an ERROR 404 on submitting. Dependencies should be installed correctly
This is my on submit function
onSubmit(e) {
e.preventDefault();
console.log(`Form submitted:`);
console.log(` ${this.state.searchquery}`);
const newSearchQuery = {
searchquery: this.state.searchquery,
};
axios.post('http://localhost:3000/', newSearchQuery)
.then(res => console.log(res.data)).then(
(response) => { console.log(response) },
(error) => { console.log(error) }
);;
this.setState({
searchquery: '',
})
}
this is the server.js file
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const todoRoutes = express.Router();
const PORT = 3000;
app.use(cors());
app.use(bodyParser.json());
todoRoutes.route('/').post(function(req, res) {
console.log(req.body);
});
app.listen(PORT, function() {
console.log("Server is running on Port: " + PORT);
});```
App is not configured to use the routes and that's why it throws a 404.
Use this line after todoRoutes.Route():
app.use(todoRoutes);
app.use() is used to register middlewares to the main node app. Since you are using router express middleware, you need to register it as well.
EDIT: This works for me. In case you want the complete code:
ReactJS:
import React from "react";
import axios from 'axios';
class App extends React.Component {
constructor() {
super();
this.state = {
searchquery: ''
};
}
handleChange = (e) => {
this.setState({ searchquery: e.target.value });
}
onSubmit = (e) => {
e.preventDefault();
console.log(`Form submitted:`);
console.log(` ${this.state.searchquery}`);
const newSearchQuery = {
searchquery: this.state.searchquery,
};
axios.post('http://localhost:3000/', newSearchQuery)
.then(res => console.log(res.data)).then(
(response) => { console.log(response) },
(error) => { console.log(error) }
);;
this.setState({
searchquery: '',
})
}
render() {
return (<form onSubmit={this.onSubmit}>
<input type="text" value={this.state.searchquery} name="searchquery" id="searchquery" onChange={this.handleChange} />
<button type="submit">Submit</button>
</form>);
}
}
export default App;
Express code:
const express = require("express");
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const todoRoutes = express.Router();
const PORT = 3000;
app.use(cors());
app.use(bodyParser.json());
todoRoutes.route('/').post(function(req, res) {
console.log(req.body);
});
app.use(todoRoutes);
app.listen(PORT, function() {
console.log("Server is running on Port: " + PORT);
});
I have to access a state from server. I want to change the twitterName with a mutation after figure out from this. I set a getter but when I try to import store to js file it sends error. How can I import a state?
server/index.js
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const path = require('path')
const app = express()
app.use(bodyParser.json())
app.use(cors())
const tweets = require('./routes/api/tweets')
const twitterName = require('./routes/api/name')
app.use('/api/tweets', tweets)
app.use('/name/', twitterName)
if (process.env.NODE_ENV === 'production') {
app.use(express.static(__dirname + '/public/'))
app.get(/.*/, (req, res) => res.sendFile(__dirname + '/public/index.html'))
}
const port = process.env.PORT || 8081
app.listen(port, () => console.log(`Server started on port ${port}`))
server/name.js
const express = require('express')
const router = express.Router()
router.get('/:twitterName', (req, res) => {
const name = req.params.twitterName
res.status(200).send(name)
})
module.exports = router
store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
twitterName: 'name1234'
},
getters: {
twitterName: (state) => state.twitterName
}
actions: {
updateId({ commit }, id) {
commit('setId', id)
},
async getTweetData({ state }) {
const res = await axios.get('http://localhost:8081/name/' + state.twitterName)
// do what you want with the data
}
},
})
You can’t use the store from the client in your express server from the simple reason that all the data used in client side of your application, including vuex store is saved in the browser, and you don’t have access to it in the server. This is not the correct way to achieve your goal.
If you want to use data from the client you need to send it to your server, so you could use it there. So if you need the twitterName specifically you can do something like this:
router.get('/tweets/:twitterName', (req, res) => {
// const name = 'name123'
const name = req.params.twitterName
T.get(
'search/tweets',
{ from: name, count: 5 },
function (err, data, response) {
if (err) {
return res.status(400).json('Oops! Something went wrong.')
}
data.twitterName = '<new-name>'
res.status(200).send(data)
}
)
})
And from the vuejs store:
actions: {
async getTweetData({ state, commit }) {
const res = await axios.get('<your-server-ip>/' + state.twitterName)
commit('setTwitterName', res.data.twitterName)
}
},
mutations: {
setTwitterName(state, newTwitterName) {
state.twitterName = newTwitterName
}
}
This is my index.js file.
import "babel-polyfill";
import http from "http";
import express from "express";
import cors from "cors";
import bodyParser from "body-parser";
import middleware from "./middleware";
import create from "./api/create";
import envVariables from "./envVariables";
import db from "./db";
let app = express();
app.server = http.createServer(app);
// 3rd party middleware
app.use(
cors({
exposedHeaders: envVariables.corsHeaders
})
);
app.use(
bodyParser.json({
limit: envVariables.bodyLimit
})
);
app.use(middleware({ envVariables, db }));
// api router
app.use("/api/create", create({ envVariables, db }));
//error handling
app.use((err, req, res, next) => {
res.status(400).json(err);
});
app.server.listen(process.env.PORT || envVariables.SERVER_PORT, () => {
console.log(`Started on port ${app.server.address().port}`);
});
export default app;
Before calling 'api/create' route, I want a middleware to be called in which I have to validate my key.
Below is my middleware index.js
const axios = require('axios');
import { Router } from 'express';
const getData = async() => {
try {
return axios.post(`https://ilp-ulamp/api/fetchToken`).then(response => {
return response.data;
}).catch(error => {
console.log(error)
})
} catch (error) {
console.log(error);
}
}
export default ({ config, db }) => {
let routes = Router();
let validateKey = async function(req, res, next) {
if(!req.body.authToken)
return res.status(401).send("Access denied. No token provided.");
else {
const resp = await getData();
if(resp.length === 0){
return res.status(403).send("Access denied");
}
else {
next();
}
}
}
return validateKey;
}
Here, the problem is, I am not getting the proper response when calling https://ilp-ulamp/api/fetchToken endpoint. I checked in Postman, this API is giving proper response but when calling this inside a middleware, it is giving response as empty.
I am not sure that I am doing it properly.
Kindly help me with this issue.
Thanks in Advance!!