Express server not responding to reqs - javascript

After sending a bunch of POST/GET reqs to the server my server stops responding and in the network tab of the console all the reqs are labeled as "pending".
I have logged timestamps during the responses but they go fast and they just don't run once the problem occurs.
Sever:
var ip = require('ip');
var fs = require('fs');
var bodyParser = require('body-parser');
var path = require('path');
var express = require('express');
var app = express();
var expressWs = require('express-ws')(app);
var students = [];
var cons = [];
app.use(bodyParser.text({
extended: true
}));
app.post('/add', function(req, res) {
students.push(req.body);
for (var i = 0; i < cons.length; i++) {
cons[i].send(JSON.stringify(students));
}
});
app.post('/del', function(req, res) {
for (var i = 0; i < students.length; i++) {
if (students[i] == req.body) {
students.splice(i, 1);
}
}
for (var i = 0; i < cons.length; i++) {
cons[i].send(JSON.stringify(students));
}
});
app.get('/students', function(req, res) {
res.send(JSON.stringify(students));
});
app.ws('/mes', function(ws, req) {
cons.push(ws);
ws.on('close', function(req) {
for (var i = 0; i < cons.length; i++) {
if (cons[i] == ws) {
cons.splice(i, 1);
}
}
});
});
Sender:
function sendData() {
if (okMes() == true) {
console.log(student_i.value);
fetch('/add', {
method: 'POST',
body: student_i.value
})
.catch(function(err) {
console.error(err);
});
student_i.value = '';
}
}
Reciever:
function placeButton(data) {
if (data.length == 0) {
error_p.style.display = 'block';
error_p.innerHTML = 'No New Students';
}
for (var i = 0; i < 200; i++) {
if (document.getElementById(i) != null) {
document.getElementById(i).remove();
}
}
students = [];
for (var i = 0; i < data.length; i++) {
student = document.createElement('button');
student.innerHTML = data[i];
students_d.appendChild(student);
students.push(student);
student.setAttribute('id', students.length - 1);
error_p.style.display = 'none';
}
for (var i = 0; i < students.length; i++) {
students[i].onclick = function() {
for (var i = 0; i < students.length; i++) {
if (students[i] == this) {
students.splice(i, 1);
}
}
// document.getElementById(this.getAttribute('id')).remove();
fetch('/del', {
method: 'POST',
body: this.innerHTML
});
if (document.querySelectorAll('button') == []) {
error_p.style.display = 'block';
error_p.innerHTML = 'No New Students';
}
}
}
}
// seting interval and fetching for '/students' and calling this func
// reciving ws.onmessage and calling this func
I have no idea why my reqs aren't being responded to and if anyone could help that would be great.

Fetch API expects full url. Change your fetch call to:
// assuming you're running on localhost on port 3000
fetch('http://localhost:3000/del', {
method: 'POST',
body: this.innerHTML
});

I just figured out the answer while testing my code. It turned out I didn't res.end() when handling post reqs and I guess it the reqs might have timed out.

Related

net::ERR_SSL_PROTOCOL_ERROR after deployment to Netlify

My shoutbox project works just find when I run it on localhost, "npm start" for the "server.js" which and I use Live Server to open "client.js" in browser. In localhost everything runs smoothly, when server starts, I can open it in browser. API request are sent good an received data parsed, display and also saved to MongoDB.
But when I deployed it onto Netlify, the following looping errors appear in the console:
"Failed to load resource: the server responded with a status of 404 (Not Found)" "polling-xhr.js:202 GET https://shoutboxbymurad.netlify.app/socket.io/?EIO=4&transport=polling&t=O1xOrfM 404 (Not "
Client.js is:
// Variables:
const socket = io('localhost:3000'); //localhost:3000
const messages = document.getElementById('messages'); // Messages field
const msgForm = document.getElementById('msgForm'); // Message form
const msgInput = document.getElementById('msgInput'); // Message input field
const userNameInput = document.getElementById('username'); // Username input field
const usrsList = document.getElementById('users-list');
var userName = '';
var onlineUsers = [];
var clientIp = '';
var clientRegion = '';
// Functions:
socket.on('welcome-message', (msg) => {
const html = `<div style="font-weight: bold; color:rgb(53, 247, 111);">${msg}</div>`;
messages.innerHTML += html;
});
socket.on('message', (msg, usr) => {
appendMessage(msg, usr);
});
const appendMessage = (message, user) => {
handleURL(message, user);
};
const handleURL = (message, user) => {
message = message.split(' ');
for (let i = 0; i < message.length; i++) {
if (message[i].includes('http' || 'https')) {
message[i] =
`${message[i]}`;
}
}
message = message.join(' ');
const html = `<div style="font-weight: bold; text-transform: uppercase; color: black; font-size: 1rem">${user}:<span style='text-transform: none;'>${message}</span></div>`;
messages.innerHTML += html;
};
socket.on('get-messages', (data) => {
let arr = [];
let limitMessages = 9; // Number of messages new connect users will get (9 by default, change if want otherwise)
for (let i = 0; i < data.length; i++) {
arr.push(JSON.parse(data[i]));
}
if (arr.length > limitMessages) {
// if number of messages in array is more than 9, then get the last 9 messages
arr = arr.slice(arr.length - limitMessages);
}
arr.map((msg) => {
const html = `<li style="color:blue;font-weight:bold; font-size: 1rem">${msg.name}:<span style="color:blue">${msg.message}<span></li>`;
messages.innerHTML += html;
});
});
socket.on('get-online-users-list', (usersData) => {
appendToOnlineBox(usersData);
});
socket.on('update-online-users-list', (data) => {
// alert(data);
removeFromOnlineBox(data);
});
const removeFromOnlineBox = (data) => {
usrsList.innerHTML = '';
let arr = [];
for (let i = 0; i < data.length; i++) {
arr.push(JSON.parse(data[i]));
}
onlineUsers.length = 0;
for (let i = 0; i < arr.length; i++) {
if (!onlineUsers.includes(arr[i].name)) {
onlineUsers.push(arr[i].name, arr[i].ip, arr[i].clientRegion);
}
}
onlineUsers.map((user) => {
let onlineUser = `<li style="border: 4px solid blue; padding:0px; margin:0"><div style="border: 2px solid green; padding:0">${user}</div></li>`;
usrsList.innerHTML += onlineUser;
});
};
const appendToOnlineBox = (data) => {
usrsList.innerHTML = '';
let arr = [];
for (let i = 0; i < data.length; i++) {
arr.push(JSON.parse(data[i]));
}
for (let i = 0; i < arr.length; i++) {
if (!onlineUsers.includes(arr[i].name)) {
onlineUsers.push(arr[i].name, arr[i].ip, arr[i].clientRegion);
}
}
onlineUsers.map((user) => {
let onlineUser = `<li style="border: 4px solid blue; padding:0px; margin:0"><div style="border: 2px solid green; padding:0">${user}</div></li>`;
usrsList.innerHTML += onlineUser;
});
};
msgForm.addEventListener('submit', (e) => {
e.preventDefault();
socket.emit(
'chatmessage',
userName,
socket.id,
msgForm.msg.value,
clientIp,
clientRegion
);
msgForm.msg.value = '';
});
const checkUserName = () => {
msgInput.disabled = true;
userNameInput.addEventListener('change', () => {
if (userNameInput.value !== '') {
msgInput.disabled = false;
userNameInput.disabled = true;
userName = userNameInput.value;
}
});
};
// GET CLIENT INFO:
const getClientIpAndRegion = () => {
fetch('http://www.geoplugin.net/json.gp')
.then((res) => res.json())
.then((data) => {
clientIp = data.geoplugin_request;
clientRegion = data.geoplugin_countryName;
});
};
// Function calls:
checkUserName(); // Check if a user inserted a useraname
getClientIpAndRegion(); // Get clients' IP address and client Geolocation (region)
Server.js is:
const mongoose = require('mongoose'); // get mongoose
const mongoDB =
'....';
mongoose
.connect(mongoDB, {
useUnifiedTopology: true,
useNewUrlParser: true,
})
.then(() => {
console.log('Conncected to MongoDB...');
})
.catch((err) => {
console.log(err);
});
const UsrData = require('./Models/UserDataSchema');
var io = require('socket.io')(3000, {
cors: {
origin: '*',
},
});
var user = new Object(); // Socket client user object
var userData = []; // objects array to store information on connected user's name, socket.id and message : Array of object strings
var data; // variable to hold UserData Schema
io.on('connection', (socket) => {
socket.emit('welcome-message', 'WELCOME TO THE SHOUTBOX'); // Emit welcome message to new user
io.emit('get-online-users-list', userData); // Emit online users list to new user
socket.emit('get-messages', userData); // Emit all previous messages from users to new user
socket.on('disconnect', () => {
//handle user disconnect
let arr = [];
for (let i = 0; i < userData.length; i++) {
arr.push(JSON.parse(userData[i]));
}
arr = arr.filter((user) => user.socketId !== socket.id);
userData.length = 0;
for (let i = 0; i < arr.length; i++) {
userData.push(JSON.stringify(arr[i]));
}
io.emit('update-online-users-list', userData);
});
socket.on(
'chatmessage',
(username, socketid, formValue, clientIp, clientRegion) => {
if (username !== '' && formValue !== '') {
user.name = username;
user.socketId = socketid;
user.message = formValue;
user.ip = clientIp;
user.clientRegion = clientRegion;
io.emit('message', user.message, user.name);
userData.push(JSON.stringify(user));
data = new UsrData({ data: userData }); //===> Create a new NoSQL document with userData
data.save(); // ===> Save the document to MongoDb
io.emit('get-online-users-list', userData);
}
}
);
});

Node.js fs.readFile returns previous version of the file

I made this code:
var Discord = require('discord.js');
var client = new Discord.Client();
var fs = require('fs');
var dotenv = require('dotenv');
var option = require('./assets/config.json');
dotenv.config({
path: __dirname + '/assets/.env'
});
client.on('ready', function () {
console.log(`Logged in as ${client.user.tag}`);
});
client.on('message', function (message) {
var done = false;
if (!message.content.startsWith('/')) return;
var args = message.content.substr(1).split(' ');
fs.readdir('./cmd/', function (err, list) {
for (var i = 0; i < list.length; i++) {
var cmds = require(`./cmd/${list[i]}`);
for (var x = 0; x < cmds.alises.length; x++) {
for (var a = 0; a < args.length; a++) {
if (args[a] == cmds.alises[x] && !done) {
cmds.run(client, message, args, option);
done = true;
}
}
}
}
});
});
client.login(process.env.TOKEN);
And I thought that I don't have to restart this main file when I edit the module files because in this code Node.js reads all the files instantly on messages. But when I edit the module file, I should restart the main file. Why is this thing happens?

TypeError: Parameter url must be string, not object

Came across this error, but i am very confused as to why i'm getting it because the url i'm using in my twitterClient.get is a string. I've tried chaning ports and restarting the computer, as well as searching for any syntax errors to no avail. Any help would be greatly appreciated!
'use strict';
const express = require('express'),
request = require('request'),
twitter = require('twitter'),
aryMod = require('./resources/modules/objectArrayMod.js'),
app = express();
app.set('view engine', 'pug');
app.set('views', './views');
app.use(express.json());
app.use(express.urlencoded({
extended: true
}));
app.use(express.static('resources'));
app.get('/', function(req, res) {
let twitterClient = new twitter({
consumer_key: '//////',
consumer_secret: '//////',
access_token_key: '//////',
access_token_secret: '//////'
});
twitterClient.get({
url: 'https://api.twitter.com/1.1/search/tweets.json',
qs: {
q: '#csc365'
},
json: true
}, function(err, response, body) {
let tweetAry = [];
for(let i = 0; i < body.statuses.length; i++) {
let object = body.statuses[i];
let text = unescapeText(object.text);
if(text !== ''){
let repSent = text.replace(/[^a-zA-Z ]/gi, ''),
lSent = repSent.toLowerCase(),
sentenceAry = lSent.split(' '),
numOfAnagrams = 0;
for(i = 0; i < sentenceAry.length; i++){
sentenceAry[i] = sentenceAry[i].split('').sort().join();
}
for(i = 0; i < sentenceAry.length; i++){
let anagram = false;
if(sentenceAry[i] !== -1){
for(let j = i + 1; j < sentenceAry.length; j++){
if(sentenceAry[j] !== -1){
if(sentenceAry[j] === sentenceAry[i]){
numOfAnagrams++;
sentenceAry[j] = -1;
anagram = true;
}
}
}
}
if(anagram){
numOfAnagrams++;
}
sentenceAry[i] = -1;
tweetAry.push({
text: text,
anaScore: numOfAnagrams
});
}
}
}
aryMod.aryOfObjects(tweetAry);
if (!err) {
res.render('twitter', { aryMod: aryMod });
}
else {
console.error(err);
}
});
});
let unescapeText = function(escTxt) {
return escTxt.replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');
};
const server = app.listen(3000, function () {
console.log(`Started server on port ${server.address().port}`);
});
What this server is supposed to do is dynamically use tweets containing a specific hashtag,count up the amount of anagrams per tweet, where a separate AJAX file comes in and load them to the page, lets you click them,and keeps score of the amount of anagrams on those tweets
Looking at the node-twitter docs, it seems you should be calling twitter.get() with a url string as the first argument, and then an object containing your parameters, like so: twitterClient.get('search/tweets', params, function(err, response, body) {...})
Here's an example from their docs on how you would use the node client to search tweets:
client.get('search/tweets', {q: 'node.js'}, function(error, tweets, response) {
console.log(tweets);
});

Respond to request after all data is inserted to database

I am trying to implement multiple data insertion on one call and trigger response only after all data is inserted. This is how I am currently doing it:
create: function(req, res) {
var response = {};
var num = req.body.num;
var ret = 0;
for (var i = 0; i < num; i++) {
var db = new user();
db.enabled = false;
db.save(function(err){
if(err) {
// Handle error
} else {
ret++;
// Do something
}
});
}
response = {"status" : 200, "message" : "It's working: " + ret};
res.json(response);
}
The problem with this approach is that all the callbacks for save will be triggered after res.json(response) which is wrong because sometimes I would also like to inform user how much data was saved. User will always receive the following response:
It's working: 0
Because ret variable is always 0. It's getting increased only after response is already triggered. What am I doing wrong?
EDIT:
Code after Will's suggestion:
var Q = require('q');
create: function(req, res) {
var response = {};
var num = req.body.num;
var ret = 0;
var tasks = [];
for (var i = 0; i < num; i++) {
var db = new user();
db.enabled = false;
tasks.push(db.save());
}
Q.all(tasks).then(
function(results) {
response = {"status" : 200, "message" : "It's working!"};
},
function(err) {
response = {"status" : 500, "message" : "Not working!" };
);
res.json(response);
}
for (var i = 0; i < num; i++) {
var db = new user();
db.enabled = false;
db.save(function(err){
if(err) {
// Handle error
} else {
ret++;
if(ret == num){
response = {"status" : 200, "message" : "It's working: " + ret};
res.json(response);
}
}
});
}

Displaying node.js file inside a node.js server?

Trying to display this node.js file through my node.js server. However, all it does is display the code in proper format as if it were in notepad rather than actually displaying what it does in the console when executed. So in other words, I want my node.js file to execute and display on the browser, not just have the code display on the webpage.
var fs = require('fs');
var colour = require('colour');
var array = fs.readFileSync('songs/sister_golden_hair.txt').toString().split("\n");
var chordsArray =[];
var lyricsArray =[];
var count1 = 0;
for(var line in array) {
count1++;
if (count1 >= 3) {
var count2 = 0;
lyricsArray[count1-3] = [];
chordsArray[count1-3] = [];
while (array[line].indexOf("[") != -1) {
lyricsArray[count1-3][count2] = array[line].substring(0, array[line].indexOf("["));
array[line] = array[line].substring(array[line].indexOf("[")+1, array[line].length);
chordsArray[count1-3][count2] = array[line].substring(0, array[line].indexOf("]"));
array[line] = array[line].substring(array[line].indexOf("]")+1, array[line].length);
count2++;
}
if (array[line].length > 0) {
lyricsArray[count1-3][count2] = array[line];
chordsArray[count1-3][count2] = "";
}
}
else {
console.log(array[line]);
}
}
for (var i = 0; i < chordsArray.length; i++) {
for (var j = 0; j < chordsArray[i].length; j++) {
if (j == 0) {
for (var k = 0; k < lyricsArray[i][j].length; k++) {
process.stdout.write(" ");
}
process.stdout.write(chordsArray[i][j].green);
}
else {
for (var k = 0; k < lyricsArray[i][j].length - chordsArray[i][j-1].length; k++) {
process.stdout.write(" ");
}
process.stdout.write(chordsArray[i][j].green);
}
}
console.log();
for (var j = 0; j < lyricsArray[i].length; j++) {
process.stdout.write(lyricsArray[i][j].yellow);
}
}
and here is the node.js server I am running where I try to say that if the client goes to "http://127.0.0.1/sister_golden_hair.html" then it should display the above node.js Here is the node.js server:
var http = require('http');
var fs = require('fs');
var counter = 1000;
function serveStaticFile(res, path, contentType, responseCode){
if(!responseCode) responseCode = 200;
fs.readFile(__dirname + path, function(err, data){
if(err){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('[' + counter++ + ']: ' + '500 INTERNAL FILE ERROR' + '\n');
}
else {
res.writeHead(responseCode , {'Content-Type': contentType});
res.end(data);
}
});
}
http.createServer(function (request,response){
var path = request.url.replace(/\/?(?:\?.*)$/,'').toLowerCase();
//write HTTP header
var page = '';
switch(path){
case '/sister_golden_hair.html':
serveStaticFile(response,
'/Problem4.js',
'application/javascript');
break;
}
}).listen(3000, "127.0.0.1");
console.log('Server Running at http://127.0.0.1:3000 CNTL-C to quit');
If you want to use node.js code in the browser, you're going to need to use something like browserify.
Have you tried using eval() - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval ? Check out the warning though.

Categories

Resources