useEffect hook does not work first load and refresh - javascript

I am trying to develop a web game for school using react, next.js, express, and socket io. Right now I get the user room id and name from frontend. I want to display the usernames of the people in a lobby. I use useffect function to fetch user list from server. The issue is user list only displays on a client just when a new user joins. I does not render show users on the lobby page at the first render and the first refresh. What am I doing wrong?
import {useEffect, useState} from "react";
import io from "socket.io-client";
function Playerz(){
// const socket = io("http://localhost:8000", {transports : ['websocket']})
const [socket] = useState(() => io('http://localhost:8000'));
const [playersL, setPlayersL] = useState([
{username:"",
roomid:""}]
);
useEffect(() =>{
socket.on("receive_list", (data) => {
//let uzers = data.replace(/[\])}["{(]/g, '');
//let ucerlist = uzers.split(",");
/* let key;
for(key in data) {
if (data.hasOwnProperty(key)) {
console.log( data[key] + "\n");
}
}*/
setPlayersL(Object.values(data));
if (playersL === null) {
return null
}
console.log('bp',playersL)
})
},[playersL]);
return(
<div style={{textAlign:"center",borderBottom:"2px solids black"}}>
{
playersL ?
(playersL.map((elem) =>(
<div key={elem.username}>{elem.username}</div>))) : (<div>No posts</div>)
}
</div>
)
}
export default function Refine(){
const Xapsul = <Playerz/>;
return Xapsul;
}```
server.js
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"]
}
});
let users = []
let numofusers = 0
io.on('connection', (socket) =>{
console.log(" Connected! ");
socket.on('joinroom',(data)=>{
// console.log('joinroom! '+ data.name);
socket.join(data.room);
users.push({username: data.author,
roomid:data.room});
// console.log(`Users with ID: ${data.author} joined room: ${data.room}`);
console.log(`Users with ID: ${(JSON.stringify(users))}`);
io.emit("receive_list", (users));
});
socket.on("disconnect",()=>{
console.log("User Disconnected",socket.id);
})
app.get('/api', function(req, res){
res.json(users); //also tried to do it through .send, but there data only on window in browser
});
})
server.listen(8000)

Related

Socket.io-client on recieving event running useEffect two times

I'm trying to build a chat application,
The issue is whenever I send a emit an message to socket.io at the same time I recieve the same message two times. I got same message console.log two times.
Now this is my Server.js (Using express & Socket.io)
const express = require("express");
const app = express();
const http = require("http");
const cors = require("cors");
const { Server } = require("socket.io");
app.use(cors());
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
io.on("connection", (socket) => {
console.log(`User Connected: ${socket.id}`);
socket.on("join_room", (data) => {
socket.join(data);
console.log(`User with ID: ${socket.id} joined room: ${data}`);
});
socket.on("send_message", (data) => {
socket.to(data.room).emit("receive_message", data);
});
socket.on("disconnect", () => {
console.log("User Disconnected", socket.id);
});
});
server.listen(3001, () => {
console.log("SERVER RUNNING");
});
And this is my client's chat.js where I am sending prop of
const socket = io.connect("http://localhost:3001");
below is component
In this Chat component.
import React, { useEffect, useState } from "react";
function Chat({ socket, username, room }) {
useEffect(() => {
socket.on("receive_message", (data) => {
console.log(data);
});
return () => {
socket.off("receive_message", (data) =>
console.log(`receive_message off ${data}`)
);
};
}, [socket]);
return (
<>
<input
type="text"
placeholder="John..."
onChange={(event) => {
console.log(event.target.value);
}}
onKeyPress={(event) => {
if (event.key === "Enter") {
socket.emit("send_message", {
room: room,
author: username,
message: event.target.value,
});
}
}}
/>
</>
);
}
export default Chat;
After opening second tab I see two console.logs popping up with the same message. Can anybody tell me what I am doing wrong here or missing here?
I have tried removing React.StrictMode from index.js, it resolves the issue but I don't want to remove it. Also after shifting my react version from 18 to 17 it also resolves the issue, how I can tackle this issue in 18. Also I want to cover that issue in same chat.js component. Any help would be appreciated.
Thanks.
The problem is here:
useEffect(() => {
socket.on("receive_message", (data) => {
console.log(data);
});
return () => {
socket.off("receive_message", (data) =>
console.log(`receive_message off ${data}`)
);
};
}, [socket]);
You are properly trying to remove a listener on the return, but the problem is that you are removing the wrong listener--you have to pass the exact same function that you want to remove (because you can have two listeners on an event). This means that when the second render occurs during safe mode, you have two listeners added to that event.
Try this:
useEffect(() => {
const receiveMessage = (data) => {
console.log(data)
}
socket.on("receive_message", receiveMessage);
return () => {
socket.off("receive_message", receiveMessage);
};
}, [socket]);
That will make sure that the right function is removed. If this works, please make sure to mark my answer!

Why socket.io drops my entire server when emitting 2 events at the same time?

I'm building an e-commerce with chat. I have 2 react apps, a customer's app, and a owner's/admin's app. I can send from customer to admin in real time messages in chat/:customer component, but I want at the same time to emit an event to admin's navbar to update the inbox messages, so when a message is sent to be notified real time. Once I created this, and send a message from customer, on page refresh the entire node js server drops. Why does this happen? Bellow you can see my code:
Owner/admin NavBar(This drops my server):
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome"
import { faAngleDown } from "#fortawesome/free-solid-svg-icons"
import "../css/navBar.css"
import { useEffect, useState } from "react"
import { Link } from 'react-router-dom';
import { socket } from "./privateChat";
export const NavBar = () => {
/*I added useEffect, because otherwise the function catalogueChoices()
works only on second click!*/
useEffect(() => {
let addProduct = document.getElementById("addProduct")
let preview = document.getElementById("preview")
addProduct.style.display = "none"
preview.style.display = "none"
socket.on('new message', (data) => console.log(data))
return () => {
socket.off('new message', (data) => console.log(data))
}
}, [])
//The function that shows and hide the cataloque submenu on nav-bar.
const catalogueChoices = () => {
let addProduct = document.getElementById("addProduct")
let preview = document.getElementById("preview")
let catalogue = document.getElementById("catalogue")
let display = preview.style.display
if(display === "none"){
addProduct.style.display = "initial"
preview.style.display = "initial"
catalogue.style.height = "150px"
} else {
addProduct.style.display = "none"
preview.style.display = "none"
catalogue.style.height = "70px"
}
}
return( <div className="navBar">
<ul>
<li>
Dashboard
</li>
<li id="catalogue">
<p>Products
<span>
<button onClick={ catalogueChoices } className="angleDown" >
< FontAwesomeIcon icon={ faAngleDown } />
</button>
</span>
</p>
<Link id="addProduct" className="products" to="add-product">Add Product</Link>
<Link id="preview" className="products" to="preview">Preview</Link>
</li>
<li>
Orders
</li>
<li>
Customers
</li>
<li >
{ newMessage } </span>
</li>
</ul>
</div>
)
}
Owner/admin private chat component(works fine without navbar socket)
import "../css/chat.css"
import io from 'socket.io-client';
import {useParams} from 'react-router-dom';
import { useEffect, useState } from "react";
import { showMessage } from "../functions/chat";
import axios from "axios"
//Initializing socket.io and url's parameter name object.
export const socket = io(`http://localhost:5000`)
/*Below component is dynamically generated in order to chat with
a specific customer that sent us a message*/
export const PrivateChat = () => {
//The state needed.
const [messagesHistory, setMessagesHistory ] = useState([])
const params = useParams();
useEffect(() => {
//Holding customer's name from url in a variable.
let customer = params.customer
//Fetching all the old messages to be displayed.
axios.get('http://localhost:5000/chat-messages')
.then( res => {
let messages = res.data.filter(item => item.Customer === customer)
if(messagesHistory.length !== messages.length) setMessagesHistory(messages)
})
//Handling the socket.io event that will send us a message from admin and displaying it.
socket.on('customer '+ params.customer, (data)=> { let sender = data.sender === 'admin' ? 'me' : data.sender
let message = data.message
if(data.sender !== 'admin') showMessage(sender, message)
})
return () => {
socket.off('customer '+ params.customer, (data)=> { let sender = data.sender === 'admin' ? 'me' : data.sender
let message = data.message
if(data.sender !== 'admin') showMessage(sender, message)
})
}
}, [])
/*The function to send a message to a customer in real time,
saving it in the database and displaying it.*/
const sendMessage = (e) => {
e.preventDefault()
let username = params.customer
let message = document.getElementById("input").value
let data = { username: username,
message: message,
sender: 'admin'
}
socket.emit('chat message', data)
axios.post('http://localhost:5000/chat-messages', data )
showMessage("me", message)
}
return(<div className="chat">
<ul id="messages">
{ messagesHistory.map( item => <li>{(item.Sender === "admin" ? "me" : item.Sender) + ": " + item.Message}</li>) }
</ul>
<form id="form" action="" onSubmit={sendMessage}>
<input id="input" /><button>Send</button>
</form>
</div>)
}
customer's app:
import "../css/chat.css"
import io from 'socket.io-client';
import { useEffect, useState } from "react"
import { showMessage } from "../functions/chat";
import {useParams} from 'react-router-dom';
import axios from 'axios'
//The dynamically created component we are redirected to when we enter our username to chat with admin.
export const Chat = () => {
//The state needed
const [messagesHistory, setMessagesHistory ] = useState([])
//Initializing socket.io and url's parameter name object.
const socket = io(`http://localhost:5000`);
const params = useParams()
useEffect( () => {
//Holding customer's name from url in a variable.
let customer = params.username
//Fetching all the old messages to be displayed.
axios.get('http://localhost:5000/chat-messages')
.then(res => {
let messages = res.data.filter(item => item.Customer === customer)
if(messagesHistory.length !== messages.length) setMessagesHistory(messages)
})
//Handling the socket.io event that will send us a message from a specific customer and displaying it.
socket.on('customer '+ customer, (data) => { let sender = data.sender === customer? 'me' : 'admin'
let message = data.message
if(data.sender === 'admin') showMessage(sender, message)
console.log(0)
})
}, [])
/*The function to send a message to the admin in real time,
saving it in the database and displaying it.*/
const sendMessage = (e) => {
e.preventDefault()
let username = params.username
let sender = params.username
let message = document.getElementById("input").value
let data = { sender: sender,
message: message,
username: username
}
socket.emit('chat message', data)
axios.post('http://localhost:5000/chat-messages', data )
showMessage("me", message)
}
return(<div className="chat">
<ul id="messages">
{ messagesHistory.map( item => <li>{(item.Sender === "admin"? "admin" : "me") + ": " + item.Message}</li>) }
</ul>
<form id="form" action="" onSubmit={ sendMessage } >
<input id="input" /><button>Send</button>
</form>
</div>)
}
The common server for socket.io and shared Apis:
const express = require("express")
const app = express()
//Creating a new server for socket.io with express
const server = require('http').createServer(app)
//The socket.io server instance attached to an instance of http.Server.
const io = require('socket.io')(server, {
cors: {
origin: "*",
methods: ["GET", "POST"],
}
})
const port = process.env.PORT || 5000
const cors = require("cors")
const db = require('./database/db')
//The middlewares needed to exchange data with frontend.
app.use(cors())
app.use(express.urlencoded({extended: true}));
app.use(express.json())
//db.query("DELETE FROM chat_messages")
//------> Socket.io configurations. <------
io.on('connection', (socket) => {
/*When server receives a message from a customer or admin, we dynamically create an event
depending on customer's name, and emit it with the message to both parties. */
socket.on('chat message', (data) => {
let name = data.username
let sender = data.sender
let message = data.message
io.emit('customer ' + name, { message: message,
sender: sender})
io.emit('new message', 1)
})
})
//Importing routes
const productsRoute = require("./routes/products")
const chatRoute = require("./routes/chat")
app.use('/products', productsRoute)
app.use('/chat-messages', chatRoute)
server.listen(port, () => console.log(`App is listening on port ${port}`))
I found the solution alone. When i emit message and at the same time axios.post to save it, crushes the connection with the database and doesnt fetch anything. I had to save it from the server while grabbed from server side socket.io. Why there is anywhere this detail? Am I Columbus who found socket.io message saving?!!

React does not update before another socket.io message

I have a node.js socket.io server that emits two messages with a 1000 ms delay. The messages are logged fine in the react app, however if I remove the 1000 ms delay, react does not update the first message's state before the second one is received.
The only way I was able to fix this issue was by using a global variable to store the first message. Is there a solution without a global variable?
Server code:
const app = express();
const http = require("http");
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server, {
cors: {
origin: "*",
},
});
io.on("connection", (socket) => {
socket.emit("data1", "First data");
setTimeout(() => {
socket.emit("data2", "Second data");
}, 1000);
});
server.listen(3001, () => {
console.log("listening on *:3001");
});
Working react app using global variable:
var data1;
export default function Main() {
const socket = useContext(SocketContext);
const onData1 = useCallback((data) => {
console.log("Received data1:", data);
data1 = data;
}, []);
const onData2 = useCallback(
(data) => {
console.log("Received data2:", data);
console.log("Data1 is:", data1);
},
[data1]
);
useEffect(() => {
console.log("Binding socket listeners...");
socket.on("data1", onData1);
socket.on("data2", onData2);
return () => {
console.log("Unbinding socket listeners...");
socket.off("data1", onData1);
socket.off("data2", onData2);
};
}, [socket, onData1, onData2]);
return <></>;
}
Not working react app:
export default function Main() {
const socket = useContext(SocketContext);
const [data1, setData1] = useState("");
const onData1 = useCallback((data) => {
console.log("Received data1:", data);
setData1(data);
}, []);
const onData2 = useCallback(
(data) => {
console.log("Received data2:", data);
console.log("Data1 is:", data1);
},
[data1]
);
useEffect(() => {
console.log("Binding socket listeners...");
socket.on("data1", onData1);
socket.on("data2", onData2);
return () => {
console.log("Unbinding socket listeners...");
socket.off("data1", onData1);
socket.off("data2", onData2);
};
}, [socket, onData1, onData2]);
return <></>;
}

How can I fetch one specific data's detail from MySQL by using Axios or other function in React?

I'm figuring out how to fetch one specific data's detail from the MySQL database.
I'm not good ad English, but I will try to explain what the response that I want looks like.
I'll show my code down below!!
This is my server index.js
const express = require('express');
const app = express();
const mysql = require('mysql');
const cors = require('cors');
app.use(cors());
app.use(express.json());
const db = mysql.createConnection({
user: 'root',
host: 'localhost',
password: 'root',
database: 'root',
});
/* GET */
app.get('/cows', (req, res) => {
const sqlSelect =
'SELECT cid, cname, cname_eng, c_img, tname FROM type t LEFT JOIN cow c ON c.c_type1 = t.tid ORDER BY cid';
db.query(sqlSelect, (err, result) => {
if (err) {
console.log(err);
} else {
// res.send("Success");
res.send(result);
}
});
});
app.get('/cows_detail/:name', (req, res) => {
const engName = req.body.name;
const sqlSelect =
'SELECT c.cid, c.cname, cname_eng, tname, c.rune1, c.rune2, c.c_eq, c.su_skill, c.c_img FROM type t LEFT JOIN cow c ON c.c_type1 = t.tid WHERE cname_eng = ? ORDER BY cid';
db.query(sqlSelect, [engName], (err, result) => {
if (err) {
console.log(err);
} else {
// res.send("Success");
res.send(result);
}
});
});
app.listen(4000, () => {
console.log('Your server is start running on port 4000');
});
And in React frontend, this is my CowsDetail.js
import React, { useState, useEffect } from 'react';
import { useParams, useHistory, Route, useLocation } from 'react-router-dom';
import Axios from 'axios';
const CowsDetail = ({ match }) => {
const history = useHistory();
const { name } = useParams();
useEffect(() => {
fetchDetail();
}, []);
const fetchDetail = async () => {
const result = await Axios.get(
`http://localhost:4000/cows_detail/${match.params.name}`
).catch((err) => console.log('Error:', err));
if (result && result.data) setCowDetails(result.data);
console.log('result', result.data); //console: []
console.log('match name', match.params.name); // examples: Jerry
console.log('match', match);
//isExact: true
//params: {name: "Jerry"}
//path: "/cows_detail/:name"
//url: "/cows_detail/Jerry"
//__proto__: Object
const [cowDetails, setCowDetails] = useState({});
const handleBackClick = () => {
history.goBack();
};
return (
<div>
<h1>Cow {name}'s Detail Pages</h1>
<button
onClick={() => {
handleBackClick();
}}
>
Back to the Cow Page
</button>
</div>
);
};
export default CowsDetail;
And here is the questions,
I have a component <Cow /> which URL is localhost:3000/cow, and when
I click one of it(for example: <Cow name='Jerry'/>),
I want the path link to => localhost:3000/cow_detail/Jerry
and show more Cow Jerry's Detail.
What can I do when I just want to only take Jerry details??
Hope I didn't make this question more complicated, thank you, guys!!

Can't create new route in index.js in node+express website on heroku

I had the following index.js file:
const express = require('express');
const path = require('path');
const generatePassword = require('password-generator');
const fetch = require('node-fetch');
const FetchTweets = require('fetch-tweets');
const request = require('request');
const TW_URL = "http://1.1/search/tweets.json" // Twitter search URL
const SEN_URL = "http://www.sentiment140.com/api/bulkClassifyJson" // URL of sentiment analysis
var TW_KEYS = {
consumer_key: process.env.TW_KEY,
consumer_secret: process.env.TW_SECRET
}
const app = express();
const fetchTweets = new FetchTweets(TW_KEYS);
// Serve static files from the React app
app.use(express.static(path.join(__dirname, 'client/build')));
// Put all API endpoints under '/api'
app.get('/api/passwords', (req, res) => {
const count = 5;
// Generate some passwords
const passwords = Array.from(Array(count).keys()).map(i =>
generatePassword(12, false)
)
// Return them as json
res.json(passwords);
console.log(`Sent ${count} passwords`);
});
// The "catchall" handler: for any request that doesn't
// match one above, send back React's index.html file.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname+'/client/build/index.html'));
});
const port = process.env.PORT || 5000;
app.listen(port);
console.log(`Password generator listening on ${port}`);
Along with my react App.js:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
// Initialize state
state = { passwords: [] }
// Fetch passwords after first mount
componentDidMount() {
this.getPasswords();
}
getPasswords = () => {
// Get the passwords and store them in state
fetch('/api/passwords')
.then(res => res.json())
.then(passwords => this.setState({ passwords }));
}
render() {
const { passwords } = this.state;
return (
<div className="App">
{/* Render the passwords if we have them */}
{passwords.length ? (
<div>
<h1>5 Passwords.</h1>
<ul className="passwords">
{/*
Generally it's bad to use "index" as a key.
It's ok for this example because there will always
be the same number of passwords, and they never
change positions in the array.
*/}
{passwords.map((password, index) =>
<li key={index}>
{password}
</li>
)}
</ul>
<button
className="more"
onClick={this.getPasswords}>
Get More
</button>
</div>
) : (
// Render a helpful message otherwise
<div>
<h1>No passwords :(</h1>
<button
className="more"
onClick={this.getPasswords}>
Try Again?
</button>
</div>
)}
</div>
);
}
}
export default App;
It worked beautifully. Now, I want to add a new route so I've changed index.js to:
const express = require('express');
const path = require('path');
const generatePassword = require('password-generator');
const fetch = require('node-fetch');
const FetchTweets = require('fetch-tweets');
const request = require('request');
const TW_URL = "http://1.1/search/tweets.json" // Twitter search URL
const SEN_URL = "http://www.sentiment140.com/api/bulkClassifyJson" // URL of sentiment analysis
var TW_KEYS = {
consumer_key: process.env.TW_KEY,
consumer_secret: process.env.TW_SECRET
}
const app = express();
const fetchTweets = new FetchTweets(TW_KEYS);
// Serve static files from the React app
app.use(express.static(path.join(__dirname, 'client/build')));
app.get('/api/sentiment', async (req, res) => {
console.log("matched /api/sentiment pattern")
const options = {
q : req.query.q,
lang : "en",
count : 100,
}
try{
fetchTweets.byTopic(options, async function(results){
const tweets = {"data": results.map(function(tweet){
return {"text": tweet.body, "query": options.q}
})}
var body = JSON.stringify(tweets)
// get sentiments
const sentiments = await fetch(SEN_URL, {method: "POST", body: body})
const json = await sentiments.json()
const data = json.data
//console.log(data)
// calculate percentages
const response = {positive: undefined, neutral: undefined, negative: undefined}
var numPos = 0
var numNeu = 0
var numNeg = 0
//console.log(response)
data.forEach(function(tweet){
switch(tweet.polarity){
case 4:
numPos += 1
break
case 2:
numNeu += 1
break
case 0:
numNeg += 1
break
}
})
const tot = numPos + numNeu + numNeg
response.positive = numPos/tot
response.neutral = numNeu/tot
response.negative = numNeg/tot
// send response
res.send(response)
})
}catch (error){
console.log(error)
}
})
// Put all API endpoints under '/api'
app.get('/api/passwords', (req, res) => {
const count = 5;
// Generate some passwords
const passwords = Array.from(Array(count).keys()).map(i =>
generatePassword(12, false)
)
// Return them as json
res.json(passwords);
console.log(`Sent ${count} passwords`);
});
// The "catchall" handler: for any request that doesn't
// match one above, send back React's index.html file.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname+'/client/build/index.html'));
});
const port = process.env.PORT || 5000;
app.listen(port);
console.log(`Password generator listening on ${port}`);
Note the new route /api/sentiments. I've also made a call to this new URL path in my App.js:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
// Initialize state
state = { passwords: [] }
// Fetch passwords after first mount
componentDidMount() {
this.getPasswords();
this.getSentiments();
}
getSentiments = () => {
fetch("/api/sentiment?q=hello")
.then(res => console.log(res))
}
The getSentiments function is what does the api call to the new route. But this doesn't work. Here's the browser console message:
GET https://glacial-refuge-37109.herokuapp.com/api/sentiment?q=hello 503 (Service Unavailable)
i.getSentiments # App.js:15
value # App.js:11
commitLifeCycles # react-dom.production.min.js:159
C # react-dom.production.min.js:185
w # react-dom.production.min.js:182
g # react-dom.production.min.js:181
v # react-dom.production.min.js:181
h # react-dom.production.min.js:180
s # react-dom.production.min.js:179
t # react-dom.production.min.js:190
updateContainer # react-dom.production.min.js:191
nn.render # react-dom.production.min.js:228
(anonymous) # react-dom.production.min.js:242
unbatchedUpdates # react-dom.production.min.js:188
ln # react-dom.production.min.js:242
render # react-dom.production.min.js:244
(anonymous) # index.js:7
t # bootstrap 8940ebd453621d06336e:19
(anonymous) # main.1f99a125.js:526
t # bootstrap 8940ebd453621d06336e:19
(anonymous) # bootstrap 8940ebd453621d06336e:62
(anonymous) # bootstrap 8940ebd453621d06336e:62
App.js:16 Response {type: "basic", url: "https://glacial-refuge-37109.herokuapp.com/api/sentiment?q=hello", redirected: false, status: 503, ok: false, …}
Looks like I'm getting 503, service unavailable. Why? How can I make this work? Btw, this works fine locally.
Add a res.send within your catch block
app.get('/api/sentiment', async (req, res) => {
console.log("matched /api/sentiment pattern")
const options = {
q : req.query.q,
lang : "en",
count : 100,
}
try{
fetchTweets.byTopic(options, async function(results){
const tweets = {"data": results.map(function(tweet){
return {"text": tweet.body, "query": options.q}
})}
var body = JSON.stringify(tweets)
// get sentiments
const sentiments = await fetch(SEN_URL, {method: "POST", body: body})
const json = await sentiments.json()
const data = json.data
//console.log(data)
// calculate percentages
const response = {positive: undefined, neutral: undefined, negative: undefined}
var numPos = 0
var numNeu = 0
var numNeg = 0
//console.log(response)
data.forEach(function(tweet){
switch(tweet.polarity){
case 4:
numPos += 1
break
case 2:
numNeu += 1
break
case 0:
numNeg += 1
break
}
})
const tot = numPos + numNeu + numNeg
response.positive = numPos/tot
response.neutral = numNeu/tot
response.negative = numNeg/tot
// send response
res.send(response)
})
}catch (error){
console.log(error)
res.send(error)
}
})
Your function is failing and because you don't send a response, hangs forever

Categories

Resources