Hi I am trying to make a request and receive just the response in realtime using socketIO
and currently I am able to connect to the router but not getting any response as the error shows
Error: io is not defined.
If anyone can please help me to resolve this issue.
Below is the necessary code.
ChatPageProvider.dart
Future<void> addProduct(String message) async {
Map<String, String> headers = {
"Content-Type": "charset=utf-8",
"Content-type": "application/json"
};
const url = 'http://localhost:8080/message/check';
try {
var response = await http.post(url,
headers: headers,
body: json.encode({
"text": message,
}));
socketIO.init();
//Subscribe to an event to listen to
socketIO.subscribe('message', (jsonData) {
//Convert the JSON data received into a Map
Map<String, dynamic> data = json.decode(jsonData);
messages.add(data['message']);
notifyListeners();
});
socketIO.connect();
// final getMessage = Message(
// text: json.decode(response.body)['message'],
// );
print(response.statusCode);
notifyListeners();
} catch (error) {
throw error;
}
}
index.js
const express = require('express');
const app = express();
const notificationdetails = require('../nodePractice/router/notification');
const http = require('http').createServer(app);
const io = require('socket.io')(http);
bodyParser = require('body-parser');
var port = process.env.PORT || 8080;
app.use(bodyParser.json({limit: "50mb"}));
app.use(bodyParser.urlencoded({limit:"50mb",extended:true}));
io.on("connection",(userSocket) => {
console.log('Conntected to port')
io.emit('connected', 80);
})
var server = http.listen(port, ()=> {
console.log('listening on port' + port)
})
app.use(notificationdetails);
notification.js
const express = require('express');
const router = new express.Router()
router.post('/message/check',async(req,res) => {
console.log("Success"); // I am able to get till here but then the error occurs
io.emit("message", req.body)
try {
res.status(201).send();
io.emit("message", req.body)
}catch(e) {
res.status(401);
io.emit("message", req.body)
res.send(e);
}
})
module.exports = router
error
(node:78214) UnhandledPromiseRejectionWarning: ReferenceError: io is not defined
You can create a file like below, give it a name socket-io.js.
var io = require('socket.io')(9999);
module.exports = io;
Then import it first in your index.js like below snippet.
let io = require('./app/utilities/socket-io');
io.on('connection', function (socket) {
...
});
Last, you can import the same file in your notification.js file as well & try below code.
const express = require('express');
const router = new express.Router()
let io = require('./app/utilities/socket-io');
router.post('/message/check',async(req,res) => {
console.log("Success"); // I am able to get till here but then the error occurs
io.emit("message", req.body)
try {
res.status(201).send();
io.emit("message", req.body)
}catch(e) {
res.status(401);
io.emit("message", req.body)
res.send(e);
}
})
module.exports = router
Related
I'm relatively new to node.js and I'm trying to include socket.io into a controller. The idea is to respond to a client when an order is placed through the response object of express but in addition I'd also like to emit an event so that the restaurant owner sees the orders from all the customers coming in 'live'.
I have an index.js file in an api folder with the following code, where I export api, server and PORT:
`
const express = require('express');
const morgan = require('morgan');
const http = require('http');
const cors = require('cors');
const api = express();
const server = http.createServer(api);
const PORT = process.env.PORT || 3000;
api.use(cors());
api.use(morgan('common'));
api.use(express.urlencoded({ extended: true }));
api.use(express.json({ extended: true }));
api.use('/api/v1', require('../routers'));
api.get('/', (req, res) => {
res.send('Backend running.');
});
module.exports = { api, server, PORT };
In the root of the project I have another index.js file with the following code:
/* eslint-disable no-console */
require('dotenv').config();
const mongoose = require('mongoose');
const { api, server, PORT } = require('./api');
const { MONGO_URI } = require('./config');
mongoose.connect(
MONGO_URI,
{ useNewUrlParser: true, useUnifiedTopology: true },
)
.then(() => console.log('Connected to DB'))
.catch((err) => console.log('Error occured while trying to connect to DB', err));
api.listen(PORT, () => console.log(`Listening on ${PORT}`));
const io = require('./socket').init(server);
io.on('connection', (socket) => {
console.log('Connection success', socket.id);
socket.on('disconnect', () => {
console.log('Connection disconnected', socket.id);
});
});
I've placed the code to initialize socket.io and get an instance of it in a folder named socket with the following code in the index.js file:
/* eslint-disable consistent-return */
/* eslint-disable global-require */
const { Server } = require('socket.io');
let io;
module.exports = {
init: (server) => {
try {
io = new Server(server);
return io;
} catch (err) {
console.log(err);
}
},
get: () => {
if (!io) {
throw new Error('socket is not initialized');
}
return io;
},
};
Then I import the io instance in a controller but when I emit an event I get the error that the socket is not initialized. This is how I import the socket instance and emit an event:
const { OrdersService } = require('../services');
const io = require('../socket/index').get();
module.exports = {
create: async (req, res) => {
const { body } = req;
try {
const order = await OrdersService.create(body);
io.emit('new order', order);
res.status(201).json(order);
} catch (err) {
res.status(400).json(err);
}
},
};
What am I doing wrong? Any help would be greatly appreciated :)
I configured socket.io like I did based on previous questions that were raised on this topic here in stackoverflow.
I`m trying to create emit for the socket on post request from postman but got some troubles. I found an issue here but it seems not working for me. I have this code in my app.js
App.js
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
const http = require('http').createServer(app)
const eventsRoute = require('./routes/eventsRoute')
const io = require('socket.io')(http, {
cors: {origin: "*"},
path: '/api/events'
})
io.of('/api/events/').on('connection', socket => console.log('connected'))
...
app.use('/api/events', eventsRoute(io))
module.exports = app
And here I got eventsRoute.js code. Here, I think, is the main problem
eventsRoute.js
const express = require('express')
const errorHandler = require('../utils/errorHandler')
const router = express.Router()
const returnRouter = io => {
router.post('/', async (req, res) => {
try {
io.sockets.emit('create', req.body)
res.status(200).json({message: 'successful'})
} catch (e) {
errorHandler(e)
}
})
router.get("/", function (req, res) {
try {
res.send({})
} catch (e) {
errorHandler(e)
}
})
return router
}
module.exports = returnRouter
And on my client side, I have some code in the script tag. Here it is
<script src="https://cdn.socket.io/3.1.3/socket.io.min.js"></script>
<script>
const socket = io('ws://localhost:5000', {path: '/api/events'})
socket.on('create', data => {
console.log(data)
})
</script>
So, the main reason was in ... all files. Let's begin with index.js. I'm exporting the app. Instead of that, I have to export http. Then in app.js, I will have to change line with sockets to this
const io = require('socket.io')(http, options)
io.of('/api/events')
.on('connection', socket => {
app.use('/api/events', eventsRoute(socket))
})
edit: added a bit more code.
const express = require('express');
var bodyParser = require('body-parser');
const app = express();
var urlencodedParser = bodyParser.urlencoded({extended: false})
const {google} = require('googleapis');
const {PubSub} = require('#google-cloud/pubsub');
const iot = require('#google-cloud/iot');
const API_VERSION = 'v1';
const DISCOVERY_API = 'https://cloudiot.googleapis.com/$discovery/rest';
app.get('/', urlencodedParser, (req, res) => {
const projectId = req.query.proyecto;
const cloudRegion = req.query.region;
const registryId = req.query.registro;
const numSerie = req.query.numSerie;
const command = req.query.command;
const client = new iot.v1.DeviceManagerClient();
if (client === undefined) {
console.log('Did not instantiate client.');
} else {
console.log('Did instantiate client.');
sendCom();
}
async function sendCom() {
const formattedName = await client.devicePath(projectId, cloudRegion, registryId, numSerie)
const binaryData = Buffer.from(command);
const request = {
name: formattedName,
binaryData: binaryData,
};
return client.sendCommandToDevice(request).then(responses => res.status(200).send(JSON.stringify({
data: OK
}))).catch(err => res.status(404).send('Could not send command. Is the device connected?'));
}
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
module.exports = app;
I have this function, that I call after the client initiate: sendCom();
async function sendCom() {
const formattedName = await client.devicePath(projectId, cloudRegion, registryId, deviceId)
const binaryData = Buffer.from(command);
const request = { name: formattedName, binaryData: binaryData, };
client.sendCommandToDevice(request)
.then(responses => {
res.status(200).send(JSON.stringify({ data: OK })).end();
})
.catch(err => {
res.status(404).send('Could not send command. Is the device connected?').end();
});
}
My problem is that sendCommandToDevice gets executed perfectly, however I get the catch error.
As I understand it, it's because in the .then ends the connection.
I've looked at this and thats's what I tried, however I'm not sure I understand what's going on.
You can not use send with end.
end() is used when you want to end the request and want to respond with no data.
send() is used to end the request and respond with some data.
You can found more about it here.
I have created a simple react app. The problem which I'm finding is when I'm hitting the url, in the response, it is showing as buffer, which should not be the case.
My code
index.js
import axios from 'axios';
export const ADD_CART = "ADD_CART";
export const REMOVE_CART = "REMOVE_CART";
export const LOGIN = "LOGIN";
export const BASE_API_URL = "http://localhost:3030";
export function addToCart(item) {
console.log(window.localStorage.getItem('WCToken'))
console.log(window.localStorage.getItem('WCTrustedToken'))
var headers = {
'Content-Type': 'application/json',
'WCToken': window.localStorage.getItem('WCToken'),
'WCTrustedToken': window.localStorage.getItem('WCTrustedToken')
}
axios.post(BASE_API_URL + "/cart", {
orderItem: [
{
productId: item.uniqueID, //working for 12262
quantity: '1'
}
]
}, {headers: headers}).then(res => console.log(res))
.catch(err => console.log(err));
return {
type: ADD_CART,
payload: item
};
}
export function removeFromCart(cartList, id) {
return {
type: REMOVE_CART,
payload: cartList.filter(i => i.uniqueID != id)
};
}
export const login = () => {
return axios.post(BASE_API_URL + "/guestidentity", {}).then(res => {
window.localStorage.setItem("WCToken", res.data.express.WCToken)
window.localStorage.setItem("WCTrustedToken", res.data.express.WCTrustedToken)
return {
type: LOGIN,
payload: {}
}
}).catch(e => {
console.log(e);
return {
type: LOGIN,
payload: {}
}
});
};
server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const Client = require('node-rest-client').Client;//import it here
const app = express();
const helmet = require('helmet');
const morgan = require('morgan');
// enhance your app security with Helmet
app.use(helmet());
// use bodyParser to parse application/json content-type
app.use(bodyParser.json());
// log HTTP requests
app.use(morgan('combined'));
app.use(cors());
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
app.post('/guestidentity',(req, res) => {
console.log("Hello from Server")
var client = new Client();
// direct way
client.post("https://149.129.128.3:5443/wcs/resources/store/1/guestidentity", (data, response) => {
res.send({ express: data });
});
});
app.post('/cart',(req, res) => {
console.log("Hello from Server")
var client = new Client();
// direct way
client.post("https://149.129.128.3:5443/wcs/resources/store/1/cart", (data, response) => {
res.send({ express: data });
});
});
const port = 3030;
app.listen(port, () => console.log(`Server running on port ${port}`));
I dont know where my code is getting wrong and why buffer is showing in response. Can somebody please guide me on this. Or provide me an insight how to troubleshoot this issue.
You are sending to the client an object with the form:
{
express: data
}
And when you log that on the console you see that data is an object:
{
data: [],
type: "buffer"
}
Which means that your post request inside express is returning that object.
I have created a simple react app. The problem which I'm finding is when I'm hitting the url, in the response, it is showing as buffer, which should not be the case.
My code
index.js
import axios from 'axios';
export const ADD_CART = "ADD_CART";
export const REMOVE_CART = "REMOVE_CART";
export const LOGIN = "LOGIN";
export const BASE_API_URL = "http://localhost:3030";
export function addToCart(item) {
console.log(window.localStorage.getItem('WCToken'))
console.log(window.localStorage.getItem('WCTrustedToken'))
var headers = {
'Content-Type': 'application/json',
'WCToken': window.localStorage.getItem('WCToken'),
'WCTrustedToken': window.localStorage.getItem('WCTrustedToken')
}
axios.post(BASE_API_URL + "/cart", {
orderItem: [
{
productId: item.uniqueID, //working for 12262
quantity: '1'
}
]
}, {headers: headers}).then(res => console.log(res))
.catch(err => console.log(err));
return {
type: ADD_CART,
payload: item
};
}
export function removeFromCart(cartList, id) {
return {
type: REMOVE_CART,
payload: cartList.filter(i => i.uniqueID != id)
};
}
export const login = () => {
return axios.post(BASE_API_URL + "/guestidentity", {}).then(res => {
window.localStorage.setItem("WCToken", res.data.express.WCToken)
window.localStorage.setItem("WCTrustedToken", res.data.express.WCTrustedToken)
return {
type: LOGIN,
payload: {}
}
}).catch(e => {
console.log(e);
return {
type: LOGIN,
payload: {}
}
});
};
server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const Client = require('node-rest-client').Client;//import it here
const app = express();
const helmet = require('helmet');
const morgan = require('morgan');
// enhance your app security with Helmet
app.use(helmet());
// use bodyParser to parse application/json content-type
app.use(bodyParser.json());
// log HTTP requests
app.use(morgan('combined'));
app.use(cors());
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
app.post('/guestidentity',(req, res) => {
console.log("Hello from Server")
var client = new Client();
// direct way
client.post("https://149.129.128.3:5443/wcs/resources/store/1/guestidentity", (data, response) => {
res.send({ express: data });
});
});
app.post('/cart',(req, res) => {
console.log("Hello from Server")
var client = new Client();
// direct way
client.post("https://149.129.128.3:5443/wcs/resources/store/1/cart", (data, response) => {
res.send({ express: data });
});
});
const port = 3030;
app.listen(port, () => console.log(`Server running on port ${port}`));
I dont know where my code is getting wrong and why buffer is showing in response. Can somebody please guide me on this. Or provide me an insight how to troubleshoot this issue.
You might need to config your client as to parse response as JSON.
var options = {
mimetypes: {
json: ["application/json", "application/my-custom-content-type-for-json;charset=utf-8"]
}
};
var client = new Client(options);