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);
});
Related
I'm developing a fullstack realtime chat project using socket io. In theory it's working, but not the way I'd like. There are two problems.
1 - On my server, I store the messages in an array and send them to react through useEffect, but even so, every time I refresh the page, the previous messages only appear when I send a new message.
2 - I can only view the messages I send when I receive a message. I mean, opening two browsers with chat and testing...
Browser 1 = I send a lot of messages and Browser 2 sees them all, but I don't see my messages until Browser 2 sends me a message, so his message appears and all the messages I sent.
server
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const dotenv = require('dotenv')
const app = express();
const mongoose = require('mongoose');
const http = require('http');
const server = http.createServer(app);
const { Server } = require('socket.io');
const io = new Server(server, {
cors: {
origin: ['http://localhost:3000'],
}
});
dotenv.config();
const nameRoutes = require('./routes/nameRoutes');
app.use(express.json());
app.use(cors());
app.use(bodyParser());
app.use('/name', nameRoutes);
app.use('/', (req, res) => {
res.status(200).json({ msg: 'API IS ALIVE!' });
})
let messages = []
io.on('connection', (socket) => {
socket.on('send-message', (data) => {
messages.push(data);
socket.broadcast.emit('message-from-server', messages);
console.log(messages);
})
});
async function connection () {
const uri = process.env.MONGO_URI;
const port = process.env.PORT;
try {
await mongoose.connect(uri);
console.log('Connected to database');
server.listen(port, () => {
console.log(`Listening on port ${port}`)
});
} catch (err) {
console.log(err);
}
}
connection();
module.exports = app;
frontend
import * as C from './styles';
import { io } from 'socket.io-client';
import { useNavigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
const Chat = () => {
const navigate = useNavigate();
const [message, setMessage] = useState('');
const [chatMessages, setChatMessages] = useState([]);
const [socket, setSocket] = useState(null);
useEffect(() => {
setSocket(io("http://localhost:3010"));
}, []);
useEffect(() => {
if (socket) {
socket.on('message-from-server', (data) => {
setChatMessages(data);
})
}
}, [socket])
const handleSendMessage = () => {
if (message) {
socket.emit('send-message', { message });
setMessage('');
}
}
const handleExitChat = () => {
navigate('/');
}
return (
<C.Container>
<C.MessagesChat>
<h2>Messages</h2>
</C.MessagesChat>
{chatMessages.map(text => {
return (
<C.Messages>
<p>{text.message}</p>
</C.Messages>
)
})}
<C.MessageText>
<textarea
name=""
id=""
cols="30"
rows="10"
placeholder='Digite sua mensagem...'
value={message}
onChange={(e) => setMessage(e.target.value)}
></textarea>
<button onClick={handleSendMessage}>Enviar</button>
</C.MessageText>
<C.Logout>
<button onClick={handleExitChat}>Abandonar a conversa</button>
<button onClick={handleExitChat}>Destruir a conversa</button>
</C.Logout>
</C.Container>
)
}
export default Chat;
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
}
}
[HPM] Error occurred while trying to proxy request /api/users/ from localhost:3000 to http://localhost:5000 (ECONNRESET)
I get this error while trying to do axios.post request,
i'm running my app with concurrently (server with express and client side using react) ,
as described here I defined client/src/setupProxy.js file:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
my server.js:
const express = require('express');
const connectDB = require('./config/db');
const app = express();
//connect Database
connectDB();
//Init MiddleWare -allows to get the data from req.body
app.use(express.json());
//Define routes
app.use("/api/users", require("./routes/api/users"));
app.use("/api/auth", require("./routes/api/auth"));
app.use("/api/profile", require("./routes/api/profile"));
app.use("/api/posts", require("./routes/api/posts"));
app.get('/', (req, res) => res.send('API is running'));
//Port - first look for an environment port (when connect to heroku)
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`server listening on port: ${PORT}`);
})
and my post request in the client side:
export const register = ({ name, email, password}) => async dispatch => {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
const body = JSON.stringify({name, email, password});
try {
const res = await axios.post('/api/users/', body, config);
console.log({res});
dispatch({
type: REGISTER_SUCCESS,
payload: res.data
})
console.log('passed dispatch')
} catch (e) {
const errors = e.response.data.errors;
if(errors) {
errors.forEach(e => dispatch(setAlert(e.msg, 'danger')));
}
dispatch({
type: REGISTER_FAIL
})
}
}
any idea what I miss ?
EDIT:
I've noticed that my server using type ipv6 and client on ipv4, maybe that's the problem ? how I make them run on the same ipv ?
I am trying to call my vue api service via axios. However, it does not work at all and I am getting Network Error message on my browser console.
Could anyone advice what I did wrong? Below I have attached my code from by the client and server side.
error
api.js
const axios = require('axios')
export default () => {
return axios.create({
baseURL: 'http://localhost:1991'
})
}
api_metrics.js
import api from '#/services/api.js'
const url = api() + '/api/metrics/'
export default {
getIpAddress () {
console.log(url)
return api().get(url)
}
}
express_server.js
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const app = express()
// middleware
app.use(cors())
const metrics = require('./routes/api/metrics')
app.use('/api/metrics', metrics)
const port = process.env.PORT || 1991
app.listen(port, ()=>{
console.log(`server running on port ${port}`)
})
server_api.js
const express = require('express')
const router = express.Router()
router.get('/', (req,res)=>{
console.log('getIpAddress ')
res.send('"metrics"')
})
module.exports = router
home.vue
<template>
<p>Home</p>
</template>
<script>
export default {
data: () => ({
this.user_information = []
}),
async created () {
try {
this.user_information = await
apiService.getIpAddress()
console.log(this.user_information)
} catch (err) {
console.log(err.message)
}
}
}
</script>
I create a chrome extension in React. I am trying to download data via socket.io. I didn't get any errors, but the array is empty.
I should set the header and token, but I do not know where to do it in the app.js server. Where can I set:
const token = '12345'
headers: {
'Authorization': `Bearer $ {token}`
}
How can I set port in server app.js and endpoint in client app.jsx if I create chrome extension?
Is there any other way (other than socket.io) to receive data in the method componentDidMount() in React without reloading the page?
When I go to the address http://127.0.0.1:4001, the console.log displays to me New client connected and Error: undefined
Server
//app.js
const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const axios = require("axios");
const port = process.env.PORT || 4001;/How port in `chrome extension?`
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server); // < Interesting!
const token = "12345";
let interval;
io.on("connection", socket => {
console.log("New client connected");
if (interval) {
clearInterval(interval);
}
interval = setInterval(() => getApiAndEmit(socket), 10000);
socket.on("disconnect", () => {
console.log("Client disconnected");
});
});
const getApiAndEmit = async socket => {
try {
const res = await axios.get(
"https://b.application.com/api/v1/scores?expand=createdBy"
); // Getting the data from DarkSky
socket.emit("FromAPI", res.data); // Emitting a new message. It will be consumed by the client
} catch (error) {
console.error(`Error: ${error.code}`);
}
};
server.listen(port, () => console.log(`Listening on port ${port}`));
//index.js
const express = require("express");
const router = express.Router();
router.get("/", (req, res) => {
res.send({ response: "I am alive" }).status(200);
});
module.exports = router;
Client
//app.jsx
import socketIOClient from "socket.io-client";
class App extends Component {
constructor (props) {
super(props);
this.state = {
scores: []
endpoint: "http://127.0.0.1:4001" /How endpoint in `chrome extension`?
}
}
componentDidMount() {
const { endpoint } = this.state;
const token = "12345";
const socket = socketIOClient(endpoint);
socket.on("FromAPI", data => this.setState({ todos: data }));
}
render () {
<div>
</div>
)
}
}
export default App;
I solved it:
const getApiAndEmit = async socket => {
try {
const res = await axios.get(
"https://b.application.com/api/v1/scores?expand=createdBy",
headers: {
Authorization: `Bearer ${token}`
}
);
socket.emit("FromAPI", res.data); // Emitting a new message. It will be consumed by the client
} catch (error) {
console.error(`Error: ${error.code}`);
}
};
-----------Try Replacing app.js:- -----------------
const express = require("express");
const http = require("http");
const socketIo = require("socket.io");
const axios = require("axios");
const port = process.env.PORT || 4001;/How port in `chrome extension?`
const index = require("./routes/index");
const app = express();
app.use(index);
const server = http.createServer(app);
const io = socketIo(server); // < Interesting!
const token = "12345";
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
let interval;
io.on("connection", socket => {
console.log("New client connected");
if (interval) {
clearInterval(interval);
}
interval = setInterval(() => getApiAndEmit(socket), 10000);
socket.on("disconnect", () => {
console.log("Client disconnected");
});
});
const getApiAndEmit = async socket => {
try {
const res = await axios("https://b.application.com/api/v1/scores?expand=createdBy", {
method: 'GET',
headers: {
'Content-Type': 'application/json',
"Access-Control-Allow-Origin": "*",
'token': token
}
}); // Getting the data from DarkSky
console.log("res.data:- "+JSON.stringify(res.data,null,4));
socket.emit("FromAPI", res.data); // Emitting a new message. It wil be consumed by the client
} catch (error) {
console.error(`Error: ${error.code}`);
}
};
server.listen(port, () => console.log(`Listening on port ${port}`));
Try modifying app.jsx as:
import socketIOClient from "socket.io-client";
class App extends Component {
constructor(props) {
super(props);
this.state = {
scores: [],
receivedData:[],
endpoint: "https://b.application.com/api/v1/scores?expand=createdBy",
token: "12345"
}
this.onDataReceived = this.onDataReceived.bind(this);
this.socket = socketIOClient(this.state.endpoint, {
extraHeaders: {
Authorization: `Bearer ${this.state.token}`
}
});
this.socket.on("FromAPI", this.onDataReceived);
}
onDataReceived(receivedData) {
console.log("receivedData ", receivedData);
this.setState({
receivedData: receivedData
});
}
render() {
return(
<div></div>
)
}
}
export default App;
Try modifying app.js: function getApiAndEmit
replace the line: socket.emit("FromAPI", res.data);
io.emit("FromAPI", res.data);