here i am sending data from socket client to socket server and after receiving the request it has to send to node api
**the issue is im getting null ** on calling the socket server
below is my code
Socket Client
socket.connect();
socket.emit("posreq",JSON.stringify({ "title": "data"}));
Socket Server
var http = require('http'),
io = require('socket.io'), // for npm, otherwise use require('./path/to/socket.io')
request = require('request'),
cors = require('cors'),
server = http.createServer(function (req, res) {
// your normal server code
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end('Hello world');
});
server.listen(4000);
// socket.io
var socket = io.listen(server);
socket.on('connection', function (client) {
// new client is here!
client.on('posreq', function (postdata) {
request.post("http://localhost:3000/book", {
body: postdata
}, function (res) {
console.log(res);
client.send("post req called",postdata);
});
});
client.on('disconnect', function () {
console.log('connection closed');
});
});
Node api
const express = require('express')
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express()
const port = 3000
let books = [{
"title": "Eloquent JavaScript, Second Edition",
}];
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/book', (req, res) => {
const book = req.body;
// output the book to the console for debugging
console.log(book);
// books.push(book);
res.json('Book is added to the database');
});
I tried but unable to understand the issue
Note : How can i convert the Socket server to express js code
As far I understand you are willing to use express instead of HTTP and that will solve your problem. And in the below code, I have used express as well as HTTP. Try code below
const express=require("express")
const app=express()
const server=require("http").createServer(app)
const socket=require("socket.io")(server)
server.listen(4000,()=>console.log(`Listening to port 4000`))
socket.on('connection', function (client) {
client.on('posreq', function (postdata) {
request.post("http://localhost:3000/book", {
body: postdata
}, function (res) {
console.log(res);
client.send("post req called",postdata);
});
});
client.on('disconnect', function () {
console.log('connection closed');
});
});
May be you need few modification,
Request is depricated so better to use axios or other alternative.
const express = require("express")
const bodyParser = require("body-parser")
const axios = require('axios')
const app = express()
const httpServer = require("http").createServer(app)
const socket = require("socket.io")(server)
app.use(bodyParser.json({ limit: '16mb' }));
app.use(bodyParser.urlencoded({ limit: '16mb', extended: true, parameterLimit: 50000 }));
app.get('/', (req,res)=> res.send("Hello world"));
socket.on('connection', function (socket) {
socket.on('posreq', async (body) => {
try {
const { data } = await axios.post("http://localhost:3000/book", { body })
socket.send("post req called", data);
} catch (error) {
socket.send("post req error", error);
}
});
socket.on('disconnect', function () {
console.log('connection closed');
});
});
httpServer.listen(3000, () => console.log(`Spinning 3000`))
Related
Hi tried to build an express backend using socket io but for whatever reason I just dont get the connection events to be fired. I am using version 3.1.2 on the server and client, so thats not the issue. As soon as I start the client app, I get some log in the express server looking like this:
::ffff:127.0.0.1 - - [24/Oct/2021:11:14:10 +0000] "GET /socket.io/?EIO=4&transport=polling&t=Noo0Wgb&b64=1 HTTP/1.1" 404 149 "-" "node-XMLHttpRequest"
But the on connection event does not fire on either side.
const dotenv = require("dotenv").config();
const express = require("express");
const app = express();
const server = require("http").createServer(app);
const morgan = require("morgan");
const cors = require("cors");
const config = require("./src/config/general");
const io = require("socket.io")(server);
const SECURITY_KEY = process.env.SECURITYKEY;
//database
const connect = require("./src/config/database/connect");
app.set("json spaces", 2);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use(morgan("combined"));
//controllers
const ExchangeController = require("./src/api/exchange/exchange.controller");
const exchangeController = new ExchangeController(io); //initially wanted to socket logic in that file, but even in the server.js its not working either
const LogController = require("./src/api/log/log.controller");
const logController = new LogController();
const StrategyController = require("./src/api/strategy/strategy.controller");
const strategyController = new StrategyController();
app.set("json spaces", 2);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use(morgan("combined"));
app.use("/api/exchange", exchangeController.router);
app.use("/api/log", logController.router);
app.use("/api/strategy", strategyController.router);
io.on("connection", (socket) => {
console.log("incoming socket connection");
socket.on("buy", async (data) => {
try {
let payload = JSON.parse(data);
let symbols = payload.symbol.split(",");
let strategy;
if (payload.hasOwnProperty("strat")) {
strategy = payload.strat;
}
if (payload.security == SECURITY_KEY) {
for (let i = 0; i < symbols.length; i++) {
exchangeManager.performStrategy(strategy, symbols[i]);
}
}
} catch (error) {
console.log("io.on", error.message);
}
});
});
app.listen(config.PORT, async () => {
await connect();
console.log(`server started on port ${config.PORT}`);
});
Client side testing code
//client.js
const io = require('socket.io-client');
const socket = io("ws://localhost:3000")
// Add a connect listener
socket.on('connect', function (socket) {
console.log('Connected!');
});
socket.on('error', function (socket) {
console.log('error!');
});
I am completely lost on this and have tried everything without any success.
error solves by switching app.listen to server.listen, my bad.
I am making a Web-Notepad using Nodejs and express where all the data is gonna be saved in MongoDB. I want to grab the data through my Rest API making an HTTP request with Axion.
When I send the GET request, the program doesn't wait for the JSON file, continues and because of that, it exports an undefined file with the site is getting shown without the data.
With the console.log after the GET request, I get all the data I need - but too late.
app.js:
const express = require('express');
const chalk = require('chalk');
const debug = require('debug')('app');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
require('dotenv/config')
const app = express();
const port = 3000;
app.use(cors());
app.use(express.static('views'));
app.use(bodyParser.json());
app.set('views', './views');
app.set('view engine', 'ejs');
const postsRoute = require('./routes/posts');
// Here i import the data from the GET request
const getData = require('./routes/router');
app.use('/posts', postsRoute);
// The outcome of this log is; Promise {<pending>}
console.log(getData);
app.get('/', (req, res) => {
res.render(
'index',
{
// Here i want to send the Data to the ejs file
getData,
title: 'Notepad'
});
});
// Connect to DB
mongoose.connect(
process.env.DB_CONNECTION,
{useUnifiedTopology: true, useNewUrlParser: true, useCreateIndex: true, useFindAndModify: false}, () =>
debug('Connected correctly to MongoDB')
);
app.listen(port, () => {
debug(`Listening on port ${chalk.green(port)}`);
});
router.js where i make the GET request (i should change the name of the file...)
const axios = require('axios').default;
async function getData() {
try {
const response = await axios.get('http://localhost:3000/posts');
console.log(response);
return response.data
} catch (err) {
console.log(err);
}
}
module.exports = getData();
GET Request:
router.get('/', async (req, res) => {
try {
const posts = await post.find();
res.json(posts);
} catch (err) {
res.json({message: err})
}
});
As all my requests are working fine, I have a problem with the put. req.body stays empty and then gives that error :
errmsg: "'$set' is empty. You must specify a field like so: {$set:
{: ...}}"
PUT :
router.put('/books/:name', (req, res, next) => {
const localdb = db.client.db(process.env.DB_NAME);
const collection = localdb.collection(process.env.COLL_BOOKS);
collection.replaceOne(
{ "name": req.params.name },
{ $set: req.body },
function (err) {
if (err) throw err
res.status(201).send(true);
});
App.js
const express = require('express'),
app = express();
os = require('os');
const bodyParser = require('body-parser');
const cors = require('cors');
const router = require('./router.js')
require('dotenv').config()
app.use(cors());
app.use(bodyParser.json());
app.use('/api/v1', router);
const port = (process.env.PORT || '3001');
let server = app.listen(port, os.hostname(), () => {
let host = server.address().address,
port = server.address().port;
console.log("Example app listening at http://%s:%s", host, port);
});
axios request :
updateItem = newBook => {
Axios.put(process.env.REACT_APP_API_PATH_BOOKS + `${newBook.name}`, newBook)
.then(res => {
this.setState({ newBook: res.data });
this.props.history.push('/admin');
})
.catch(err => console.log(err));
}
I don't understand what I am doing wrong
Make sure you don't have any middlware stripping or incorrectly parsing the body. For instance, you may have a JSON body parser, and not be sending JSON data with JSON application headers.
Can you give a bit of context, in code, for how you are making the put request and also the result of logging the req in a pastebin?
I'm making a POST request from a React front-end using axios to an endpoint to save some data to my DB (MongoDB). I'm getting an error that one cannot read property 'name' of undefined. I think that's occurring because req.body is undefined but I can't understand what's wrong with my axios request. I logged all the parameters and they are there (not undefined). The axios request and the endpoint are written below. Any help will be appreciated. Thanks!
Axios Request
const uploadElement = async (name, HTMLCode, JSCode, CSSCode, screenshot) => {
console.log(name)
try {
await axios({
method: 'post',
url: '/api/elements',
data: {
name: name,
HTMLCode,
JSCode,
CSSCode,
screenshot
}
});
} catch (e) {
console.log(e);
}
}
Endpoint for POST Request
router.post("/", upload.single("screenshot"), async (req, res) => {
try {
const newElement = new Element({
name: req.body.name,
JSCode: req.body.JSCode,
HTMLCode: req.body.HTMLCode,
CSSCode: req.body.CSSCode,
screenshot: req.file.buffer,
});
await newElement.save();
res.send("Data uploaded successfully!");
} catch (e) {
console.error(e);
}
});
Server.js
const express = require("express");
const passport = require("passport");
const session = require("express-session");
const cors = require('cors');
const elementRouter = require("./routes/elementRoute");
const authRouter = require("./routes/authRoute");
const connectDB = require("./config/db");
const app = express();
const port = process.env.PORT || 5000;
connectDB();
app.use(
session({
secret: "googleOAuth",
resave: false,
saveUninitialized: true,
})
);
app.use(cors());
// Passport Config
require("./config/passport")(passport);
app.use(passport.initialize());
app.use(passport.session());
app.use("/api/elements", elementRouter);
app.use("/api/auth", authRouter);
app.listen(port, () => {
console.log(`Server is up on port ${port}`);
});
You need to install and require body-parser in your serverside code
First run npm i --save body-parser
Then require it like this
const bodyParser = require("body-parser");
Then use it after you declare your app ( after this line const app = express();)
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
This makes the data of your request available in req.body
I get a message Request is not finished yet and no data will be sent, if I do patch and delete requests in my app ( the post and get request work well)
Here are my requests
In service (front, Angular 4) I create the requests
api = 'http://localhost:3000/tasks';
deleteData(id) {
return this.http.delete( this.api, id);
}
patch(data) {
return this.http.patch( this.api, data);
}
And then call them in component
this.deleteData(this.checkedItems);
this.service.patch(result.data).subscribe(d => {
this.tasks = d;
});
The service
The PATCH request get req.body via console.log - so it should works, but it doesn't
The DELETE request doesn't get any data! The req.body is empty! But I need to pass the array of ids, so I can't do it via params.
Could you please help me or give a hint? Here is my service
const express = require('express');
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
var Schema = mongoose.Schema;
const app = express();
//Middleware for CORS
app.use(cors());
app.use(express.json());
// Parsers for POST data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Point static path to dist
app.use(express.static(path.join(__dirname, 'dist')));
var todoSchema = new Schema({
taskName: String,
createdAt: Date,
isDone: Boolean,
prioraty: String
}, {
collection: 'tasks'
});
var Model = mongoose.model('Model', todoSchema);
//replace when DB is online
mongoose.connect('mongodb://localhost:27017/admin').then(() => {
console.log("connected");
}).catch (() => {
console.log("not connected");
});
mongoose.connection.once('open', function () {
console.log('mongodb connected.');
});
app.patch('/tasks', function (req, res) {
console.log(req.body);
var updateObject = {
'taskName': req.body.taskName,
'isDone': req.body.isDone,
'prioraty': req.body.prioraty
}
var id = req.body._id;
Model.collection.update({_id : id}, {$set: updateObject});
});
app.delete('/tasks', function(req,res){
console.log('Delete', req.body);
var ids = [];
for (let i = 0; i < req.body.length; i ++) {
ids.push(req.body[i]._id);
}
var myquery = { _id: { $in: ids } };
Model.collection.deleteMany(myquery, function(err, obj) {
if (err) throw err;
});
});
const port = process.env.PORT || '3000';
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port, () => console.log(`API running on localhost:${port}`));
You need to close the connection when you're done handling the request, otherwise the client will wait for the server to send a response until the request timeout is reached.
app.patch('/tasks', function (req, res) {
...
Model.collection.update({_id : id}, {$set: updateObject}, function (err) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
res.sendStatus(200);
});
});
app.delete('/tasks', function(req,res){
...
Model.collection.deleteMany(myquery, function(err) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
res.sendStatus(200);
});
});
As for the DELETE request not having a req.body, that's because Angular 4's http client doesn't allow a body for DELETE requests. Its API for DELETE requests looks like this: this.http.delete(url, httpOptions), with no body support. You'll have to use query parameters if you need to send an array of ids. Query params does support arrays, they look something like this: https://myurl.xyz/tasks?ids[]=1&ids[]=2&ids[]=3
See https://angular.io/guide/http#url-parameters