React API communication refuse on cloud IDE (MERN Stack) - javascript

I'm learning MERN stack following the below tutorial.
https://medium.com/#beaucarnes/learn-the-mern-stack-by-building-an-exercise-tracker-mern-tutorial-59c13c1237a1
I've decided to use a cloud platform IDE called goorm IDE (https://ide.goorm.io) which is similar to cloud 9 IDE, and as I followed the tutorial, I realized a simple problem, that the testing environment is little different because I can not access the localhost on my machine (Or at least I don't know how to.)
Working on the back End did not have much problem because this IDE provides a domain where I can access and I could just run the server.js (not the whole react app) and test the API end point easily.
But now that I run the whole react app as I'm learning Front End side, I discovered that my server.js is not accessible as before when I was running just the server and I would get refused from the connection as below.
Below code is the actual code I'm using from the front End side in order to make API call to the server.
axios.post('http://localhost:5000/users/add', user).then(res => console.log(res.data));
// I tried changing the url to external domain.. changing the directory.. with no luck..
And below is the code for server.js file.
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
const port = process.env.PORT || 5000;
app.use(cors());
app.use(express.json());
const uri = process.env.ATLAS_URI;
mongoose.connect(uri, { useNewUrlParser: true, useCreateIndex: true }
);
const connection = mongoose.connection;
connection.once('open', () => {
console.log("Mongo DB database connection established successfully");
});
const exercisesRouter = require('./routes/exercises');
const usersRouter = require('./routes/users');
app.use('/exercises', exercisesRouter);
app.use('/users', usersRouter);
app.listen(port, process.env.IP, () => {
console.log(`Server is running on port: ${port}`);
});
And below is the url of the page where I'm actually trying to make the API Call.
https://zimen.run.goorm.io/user
Other environment information
Running URL and Port setting from the IDE : https://zimen.run.goorm.io:3000
React App directory : root/mern-exercise-tracker/
dependencies : express, create-react-app, mongoose, cors
I'm wondering if it would be better to start the whole project again in a clean local environment..
If someone could please help, it would be much appreciated.
Any other information needed, please let me know, or you can actually join the IDE online as this is a cloud IDE.
Thank you in advance.
== UPDATE ==
Sorry I've forgotten to attach the error log.
xhr.js:178 POST https://localhost:3000/users/add net::ERR_CONNECTION_REFUSED
Uncaught (in promise) Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:83)

its seems you have CORS error,i solved this problem by installing CORS extension on Goolge Chrome

Set PORT=5000 in Nodejs server-side and the default port for React frontend as PORT=3000.
Set your own separate custom 'Running URL and Port' for Nodejs and React.
Example:
https://[custom-client-side-name].goorm.io
for React at PORT=3000
and
https://[custom-server-side-name].goorm.io
for Nodejs at PORT=5000
For Axios command on React side, use:
axios.post('https://my-server-side.goorm.io/users/add', user).then(res => console.log(res.data));
and similarly, the React frontend can be found on your custom website you have set up: https://my-client-side.goorm.io/[custom-routes]

Related

Restart NodeJS app automatically after app crashes

I want to add code to my NodeJS (Express) app so that it will restart automatically after crashes with some error. I know about forever npm package, but I found only examples with running app in development, while my goal is to use it in production (app is already on production server). Should I add some code inside app.js (main file for my application) or in different files?
Here's my app.js code:
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const path = require("path");
const con = require("./databaseConnection");
const app = express();
/* Middleware */
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
/* Redirect http to https */
app.enable('trust proxy');
app.use (function (req, res, next) {
if (req.secure) {
// request was via https, so do no special handling
next();
} else {
// request was via http, so redirect to https
res.redirect('https://' + req.headers.host + req.url);
}
});
/* Routers */
const authRouter = require("./routers/authRouter");
const userRouter = require("./routers/userRouter");
app.use("/auth", authRouter);
app.use("/user", userRouter);
app.listen(5000);
I think the program you are looking for is pm2. https://pm2.keymetrics.io/docs/usage/quick-start/
You could listen for any unhandled exceptions/errors and handle them to stop the server crashing because of an uncaught error, but there are a bunch more problems that could happen with the process itself that would go unhandled such as memory leaks, which is why you need to use a process manager rather than something internal inside your express server.
It's better to use the pm2 daemon to manage the server processes for you, it also comes with a built-in dashboard, logging, and useful restarting configuration options such as
Restart app at a specified CRON time
Restart app when files have changed
Restart when app reach a memory threshold
Delay a start and automatic restart
Disable auto restart (app are always restarted with PM2) when crashing or exiting by default)
Restart application automatically at a specific exponential increasing time

NodeJs Error: Port already in use:3000 using socket.io and express

I'm making a node.js application that uses socket.io and express.
The code looks like this-
const express=require('express');
const app=express();
const http=require('http').Server(app);
app.use(express.static('public'));
const io=require('socket.io')(http,{
cors:{origin:'*'}
});
http.listen(3000,()=>{
console.log('listening to port 3000');
});
//when connection made
io.on('connection',(socket)=>{
console.log('connection made!');
});
Here,public is a folder container all the html files for the website.
Now,when I run it locally on my pc,it works fine
But when I deployed it on the glitch.com servers,i get this error:
Error: listen EADDREINUSE: address already in use :::3000
As far as i know,3000 is the only available port in glitch and I cannot use another port.
Also,the questions on stack overflow related to this topic doesn't help me since most of the answers are related to killing the running tasks themselves and I don't have permission to do so on the server.
This often happens when your server is still running in error, try switching listening to 3001 and see if there is still the error
free your 3000 port:
Linux: fuser -k 3000/tcp
According to this question on glitch.com's forums you might have two services listening to the same port, but that doesn't seem to be the case.
You should also be able to change the default listening port by setting the PORT environment variable in your .env file if you have one. Trying a different port should solve the problem
EDIT:
Apparently the problem could be the initial configuration of the server, you can try setting everything up like this:
const app = require('express')();
const server = require('http').createServer(app); <--
const io = require('socket.io')(server);
io.on('connection', () => { /* your code */ });
server.listen(process.env.PORT, () => {/* your code */});
(Got this from socket.io github page)
If this doesn't work either you should try asking on glitch.com's support forums, one of their technicians will help you better troubleshoot your problem, they have all the necessary tools

Using dotenv for API keys in multiple JS files

I am new to web programming but not programming in general. I use node.js to create a website and am using dotenv to hide API info form github and am having some trouble understanding something.
My .env file is in the root directory and contains:
GOOGLE_CALENDAR_API_KEY=key_value
I use an app.js file to set up and run my server and send the index.html file.
//jshint esversion:6
const https = require('https');
const bodyParser = require("body-parser");
const express = require("express");
require("dotenv").config();
const app = express();
app.use(express.static("public"));
app.get("/", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
app.listen(5000, function(req, res) {
console.log("Listening on port 5000.");
});
Then I have another script file I use named "custom.js" to run the bulk of my webapp. Inside, I try to use process.env to get the API key.
window.onload = function()
{
const googleAPIkey = process.env.GOOGLE_CALEDAR_API_KEY;
.
.
.
but I get an error "Uncaught ReferenceError: process is not defined"
I have also tried moving the require("dotenv").config() line to the custom.js file and that fails. There is something I am doing wrong with trying to access information from one file into another, but I don't understand what.
Any help would be appreciated!
From what's i understood you trying to access the process variable of node.js app from the client browser and it is not possible. The process variable is only accessible in the scope of the node.js application and not in the browser where you run your client.
you have to add require("dotenv").config(); on second script file also
It looks like you are trying to access the Process variable on the client-side / frontend. You cannot access those variables from a client browser or machine

Can't run puppeteer in react app, Module not found: Can't resolve 'ws' when compiling

I was wondering if it was possible to run puppeteer in my react app. Whenever I try to run puppeteer in my react app I get "Module not found: Can't resolve 'ws'". I've tried installing ws but will still get the same error.
Simple answer : You can't run puppeteer in react app.
React is a client side framework. which means it runs in browser.
While puppeteer is a NodeJS lib, it needs Node.js and runs on server side.
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.
Expanding on the above answer. You cannot directly run Puppeteer on a react app. React app is a frontend framework and you would need Puppeteer to run on a node js, server. It's a simple "fix" and I wanted to explain it a little more than the answer above does.
The steps to get them to work together would be.
Setup an express server. You can create an express server like so:
Separate directory reactServer. Npm init directory and npm i express.
In your express server you allocate a path
const express = require('express')
const app = express()
const port = 5000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.get('/my-react-path', (req, res) => {
// run any scripts you need here
})
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
Then your react app will interact with your server like so:
localhost:5000/my-react-path
In the my-react-path you can create a function that fires up puppeteer and does all the things you want on the server side and it can return whatever results to React. The above example is just to get you started it doesn't have anything related to puppeteer.

node.js /socket.io/socket.io.js not found

i keep on getting the error
/socket.io/socket.io.js 404 (Not Found)
Uncaught ReferenceError: io is not defined
my code is
var express = require('express'), http = require('http');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(3000);
and
<script src="/socket.io/socket.io.js"></script>
what is the problem ???
any help is welcome!
Copying socket.io.js to a public folder (something as resources/js/socket.io.js) is not the proper way to do it.
If Socket.io server listens properly to your HTTP server, it will automatically serve the client file to via http://localhost:<port>/socket.io/socket.io.js, you don't need to find it or copy in a publicly accessible folder as resources/js/socket.io.js & serve it manually.
Code sample Express 3.x -
Express 3 requires that you instantiate a http.Server to attach socket.io to first
var express = require('express')
, http = require('http');
//make sure you keep this order
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
//...
server.listen(8000);
Happy Coding :)
How to find socket.io.js for client side
install socket.io
npm install socket.io
find socket.io client
find ./ | grep client | grep socket.io.js
result:
./node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js
copy socket.io.js to your resources:
cp ./node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js /home/proyects/example/resources/js/
in your html:
<script type="text/javascript" src="resources/js/socket.io.js"></script>
It seems that this question may have never been answered (although it may be too late for the OP, I'll answer it for anyone who comes across it in the future and needs to solve the problem).
Instead of doing npm install socket.io you have to do npm install socket.io --save so the socket.io module gets installed in your web development folder (run this command at the base location/where your index.html or index.php is). This installs socket.io to the area in which the command is run, not globally, and, in addition, it automatically corrects/updates your package.json file so node.js knows that it is there.
Then change your source path from '/socket.io/socket.io.js' to 'http://' + location.hostname + ':3000/socket.io/socket.io.js'.
... "You might be wondering where the /socket.io/socket.io.js file
comes from, since we neither add it and nor does it exist on the filesystem. This is
part of the magic done by io.listen on the server. It creates a handler on the server
to serve the socket.io.js script file."
from the book Socket.IO Real-time Web
Application Development, page 56
You must just follow https://socket.io/get-started/chat/ and all will work.
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
http.listen(3000, function(){
console.log('listening on *:3000');
});
If you are following the socket.io tutorial https://socket.io/get-started/chat/, you should add this line as below.
app.use(express.static(path.join(__dirname, '/')))
This is because in the tutorial, Express will only catch the url
/ and send the file of index.html.
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html')
})
However, in the index.html, you have a script tag (<script src="/socket.io/socket.io.js"></script>) requests the resouce of socket.io-client, which is not routed in index.js (it can be found in console-network that the url is http://localhost:3000/socket.io/socket.io.js).
Please check the directory path mentioned in your code.By default it is res.sendFile(__dirname + '/index.html');
make sure you index.html in proper directory
Steps to debug
npm install socket.io --save in static files (index.html) for example, you may have installed it globally and when you look at the debugger, the file path is empty.
Change your script file and instantiate the socket explicitly adding your localhost that you have set up in your server file
<script src="http://localhost:5000/socket.io/socket.io.js"></script>
<script>
const socket = io.connect("localhost:5000");
$(() =>
Double check that the data is flowing by opening a new browser tab and pasting http://localhost:5000/socket.io/socket.io.js you should see the socket.io.js data
Double check that your server has been set-up correctly and if you get a CORs error npm install cors then add it to the server.js (or index.js whatever you have chosen to name your server file)
const cors = require("cors");
const http = require("http").Server(app);
const io = require("socket.io")(http);
Then use the Express middleware app.use() method to instantiate cors. Place the middleware this above your connection to your static root file
app.use(cors());
app.use(express.static(__dirname));
As a final check make sure your server is connected with the http.listen() method where you are assigning your port, the first arg is your port number, for example I have used 5000 here.
const server = http.listen(5000, () => {
console.log("your-app listening on port", server.address().port);
});
As your io.on() method is working, and your sockets data is connected client-side, add your io.emit() method with the callback logic you need and in the front-end JavaScript files use the socket.on() method again with the call back logic you require. Check that the data is flowing.
I have also edited a comment above as it was the most useful to me - but I had some additional steps to take to make the client-server connection work.
If you want to manually download "socket.io/socket.io.js" file and attaché to html (and not want to get from server runtime) you can use https://cdnjs.com/libraries/socket.io
like
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.min.js" integrity="sha512-eVL5Lb9al9FzgR63gDs1MxcDS2wFu3loYAgjIH0+Hg38tCS8Ag62dwKyH+wzDb+QauDpEZjXbMn11blw8cbTJQ==" crossorigin="anonymous"></script>
while this doesn't have anything to do with the OP, if you're running across this issue while maintaining someone else's code, you might find that the problem is caused by the coder setting io.set('resource', '/api/socket.io'); in the application script, in which case your HTML code would be <script>type="text/javascript" src="/api/socket.io/socket.io.js"></script>.
If this comes during development. Then one of the reasons could be you are running a client-side file(index.html). But what you should do is run your server(example at localhost:3000) and let the server handle that static file(index.html). In this way, the socket.io package will automatically make
<script src="/socket.io/socket.io.js"></script> available on the client side.
Illustration(FileName: index.js):
const path = require('path');
const express = require('express');
const socketio = require('socket.io');
const port = 3001 || process.env.PORT;
const app = express();
const server = http.createServer(app);
const io = socketio(server);
//MiddleWares
app.use(express.json());
app.use(
express.urlencoded({
extended: false,
})
);
app.use(express.static(__dirname + '/public'));
app.get('/', (req, res) => {
res.sendFile('index.html');
});
io.on('connect', (socket) => {
console.log('New user joined');
}
server.listen(port, () => {
console.log(`App has been started at port ${port}`);
});
After this run your server file by the command
node index.js
Then open the localhost:${port}, Replace port with given in the index.js file and run it.
It solved my problem. Hope it solves yours too.

Categories