How to connect front and back end using replit & mongodb? - javascript

I made a simple full stack app for a job application using a mern stack. The application requires the app to be deployed on replit. I was able to run my app from my laptop but I am having issue connecting my back end with my front end api calls.
I have not used replit or other online coding platforms much before, so I am not very sure how to. If I run my front end on replit and my back end from my local laptop files, the api calls are working fine. But If I run start both front and back end on replit, the server will start but no API calls will reach it.
Here is the replit link: https://replit.com/#MayurKumar4/In-replit-how-to-connect-to-mongoosemongo-api-endpoints?v=1
Below is the index page of my express app.
The dbURI is currently linked to a mongodb atlas cluster I have set up and is working with some seed data.
port is set to 4000
import express from 'express'
import mongoose from 'mongoose'
import router from './config/routes.js'
import { port, dbURI } from './config/environment.js'
import cors from 'cors'
const app = express()
const startServer = async () => {
try {
// Attempt mongodb connection
await mongoose.connect(dbURI)
console.log('Mongodb connected')
// --Middleware--
// JSON Parser
app.use(express.json())
app.use(cors())
// Logger
app.use((req, _res, next) => {
console.log(`🚨 Request received: ${req.method} - ${req.url}`)
next()
})
// Routes
app.use('/api', router)
// Catch All
app.use((_req, res) => {
return res.status(404).json({ message: 'Route Not Found' })
})
// If mongodb connects successfully
app.listen(port, () => console.log(`🚀 Server listening on port ${port}`))
} catch (err) {
console.log(err)
}
}
startServer()

Related

Backend code sending response to client side but not showing output of other lines in console log

I am running a backend code written on Node.js for my application. When I host my backend on a port, I am able to get the API response to my client side but outputs that should be displayed in console log(in Node) are not being displayed. I am assuming that when I run this code on my localhost port the entire code should be executed thus resulting in console log outputs (eg: "DB connected" should be displayed in console log). But this is not happening. Only the post request console log O/P is being displayed(i.e "response sent"). Why is this happening?
Note: The post request O/P is displayed only when I post to the backend. It is not being displayed by default which is the expected behaviour.
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import DB from "./env";
const app = express();
// DB connection
mongoose.connect(DB,{})
.then(() => {console.log("DB connected")})
.catch((error) => {error});
//middlewares
app.use(express.json({}));
app.use(cors({
origin:["http://localhost:3000"],
}));
//the actual backend response from server
app.post("/" , (req,res) => {
console.log("response sent");
//console.log(req.body.email);
//console.log(req.body);
res.end("backnd working");
})
//listen on port 8000
app.listen(8000);
Most of the things explained in comments so read it first.
// load environmental variables.
require("dotenv").config();
// require modules.
const express = require("express"),
mongoose = require("mongoose"),
cors = require("cors"),
// app contains all express stuff.
const app = express();
// showing ports of your app is dangerous.
// get port and host from .env file by using dotenv package.
const PORT = process.env.PORT || 3000,
HOST = process.env.HOST || "localhost";
// you should use a seperate file to connect to database.
// here is the implementation of db.js file.
// anonymous function it will run automatically
(async () => {
// try and catch block to handle error
try{
await mongoose.connect(process.env.DB, {
useNewUrlParser: true,
useUnifiedTopology: true
});
console.log("Connection SuccessFull");
}catch(err){
console.log(`no connection due to: ${err}`);
};
})();
// middlewares
app.use(express.json());
app.use(cors({
origin:["http://localhost:3000"],
}));
// try to use express router in a seperate file for better consistency
// The home page api
app.post("/" , (req, res) => {
console.log(`The home api hitted!
Main data is ${req.body}`);
res.status(200).send("backend working");
})
// listen app on given port and host
app.listen(PORT, HOST, (err) => {
// if error occured then this will fire else log success message to console.
if(err) console.log(err);
console.log(`The app started successfully on http://${HOST}:${PORT}/`);
});
If something wrong then please tell me i will fix it.
I am not 100% sure that this will work!
Thank you!

How to let backend file (app.js) process any url comes from the frontend

I have an Express app contains two files on the root
(index.js + index.html)
and a folder named: server, contains a file [app.js] that listening to port 3000
I run index.html through Live Server on port: 5500
In [index.html + index.js] I fetch data through buttons from port 3000 where app.js is listening on, and it working good.
But my problem is when the user type a link in the frontend (localhost:5500/NotFound), in this case the browser won’t find the link and will get an error: Cannot Get…
What I want is to show a message “Not Found” for any invalid URL comes from the frontend
my question isn’t about 404 error itself but how to let the frontend handles the navigation in the backend.
my app structure is like this:
//app.js on port:3000/backend
app.get('/test', (req, res) => res.send('This is a test'))
app.get('/*', (req, res) => res.send('Not Found'))
//OR
app.get('/*', (req, res) => {
res.sendFile(__dirname, '/404.html');
})
app.listen(3000, () => console.log(`server up`))
//index.js on port 5500/frontend
document.addEventListener('DOMContentLoaded', function () {
fetch('http://localhost:3000/test)
.then(...)
})
now let’s say that it’s in the localhost:
frontend (index.html + index.js) are on http://127.0.0.1:5500/
backend (app.js) is on http://127.0.0.1:3000/
this working good if it requested from backend http://127.0.0.1:3000/ but if the request handled from the frontend (http://127.0.0.1:5500/NoExists ) it gets [Cannot GET /NoExists]
So, how to send a message {Not Found} to http://127.0.0.1:5500/NoExists?
in other words:
let app.js (backend) triggered by any request sent from index.js(frontend)
Use the response.status method
app.get('/*', (req, res) => res.status(404).send('Not Found'))
Edit: hopefully I understand the question now
You can leave the path blank to let it work for any undefined routes
app.get((req, res) => res.status(404).send('Not Found'));
// OR
app.get((req, res) => res.status(404).sendFile(__dirname, '/404.html'));
Edit 2: So from the video you sent, I think you want to display a 404 message in the front end.
Create a file in the same location as index.html and name it 404.html. This is just a normal html file, but its contents will be displayed when a page isn't found.
It looks like you're using live server, and I've found that the 404.html file doesn't work on live server, but it will work for most hosting services. Check this article or this one.

How should I use proxy in a web app made with node.js and vanilla javascript?

I have a web app made in node.js and vanilla javascript. I wanna replace "http://localhost:4000/api/word" with "api/word" in the fetch api so that it works when the app's deployed on Heroku. I solved the issue by adding "proxy" : "http://localhost:4000" in package.json file when I used React for other apps but I don't know how to deal with the issue when I'm not using React.
server.js
const express = require("express");
const app = express();
const cors = require("cors");
const fs = require("fs");
const port = process.env.PORT || 4000;
app.use(express.json());
app.use(cors());
app.get("http://localhost:4000/api/word", function (req, res) {
fs.readFile("./wordlist.txt", (err, data) => {
if (err) throw err;
let wordList = data.toString().split("\n");
res.send(wordList);
});
});
main.js
function getWord() {
fetch("/api/word")
.then((res) => res.json())
.then((res) => {
...do something...
})
.catch((err) => console.log(err));
}
I tried the React way but it sends the get request to localhost:5500 which is the client side port.
Since your client and server are listening on different ports, I'm assuming your server isn't serving the client and that it has its own server. If the client doesn't need its own separate server, you can serve it from your express app by putting it in a directory and using express.static. Assuming you put the frontend code in a directory called public next to your server code, that would look like this:
app.use(express.json());
app.use(cors());
app.use(express.static(path.resolve(__dirname, 'public')));
If you do need to have a separate server for the client, there are modules just for this problem. http-proxy is a very popular one. I provided examples of how to use it here that could be easily adapted for any Node server, but there are many more in the docs.
Also just a sidenote, app.get("http://localhost:4000/api/word", function (req, res) should be app.get('/api/word' ...: your routes shouldn't define the scheme, host, and port.

How to deploy express.js server to Netlify

I am attempting to deploy a Vue.js, Node, Express, MongoDB (MEVN) stack application to Netlify. I successfully deployed the front end of the application to Netlify, and am now attempting to deploy the express server, based on the following serverless-http example: https://github.com/neverendingqs/netlify-express/blob/master/express/server.js
I configured my server to include the serverless-http package:
server.js
const express = require('express');
const app = express();
const serverless = require('serverless-http');
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./DB.js');
const postRoute = require('./routes');
mongoose.connect(config.DB, { useNewUrlParser: true, useUnifiedTopology: true }).then(
() => { console.log('Database is connected') },
err => { console.log('Can not connect to the database'+ err)}
);
app.use(cors());
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use('/messages', postRoute);
app.use('/.netlify/functions/server', router); // path must route to lambda
app.use('/', (req, res) => res.sendFile(path.join(__dirname, '../public/index.html')));
module.exports = app;
module.exports.handler = serverless(app);
routes.js
const express = require('express');
const postRoutes = express.Router();
// Require Post model in our routes module
let Post = require('./post.model');
// Defined store route
postRoutes.route('/add').post(function (req, res) {
let post = new Post(req.body);
post.save()
.then(() => {
res.status(200).json({'business': 'business in added successfully'});
})
.catch(() => {
res.status(400).send("unable to save to database");
});
});
// Defined get data(index or listing) route
postRoutes.route('/').get(function (req, res) {
Post.find(function(err, posts){
if(err){
res.json(err);
}
else {
res.json(posts);
}
});
});
module.exports = postRoutes;
I then re-deployed my application to Netlify, but the server does not seem to run in Netlify. This server is in a folder in project root of my vue.js app. Should I instead run the server as a separate site in Netlify? If not, what should I do in order to get the server to run when deployed in Netlify?
It's been a while, but here goes.
Netlify hosting is for the Jamstack, as they say, i.e. only static files, no processing on the server. The idea is to make use of other mechanisms to get your data dynamically, such as APIs hosted elsewhere, which you query straight from the browser, or when you build your site.
Most likely you actually had to deploy your express.js app as a Netlify Function, instead. Check Netlify's blog post on running express apps on their functions.
I had a similar issue, just that my server wouldn't connect to the routes locally, the major difference between my code and yours was that I had to do
const router = express.Router()
and then switched app.use() with router.use()
Like I said, that's for when the localhost says "cannot GET /* a defined path */"
P.S. As a side note, you don't need explicit bodyParser in recent express, express.json() works fine instead.

Implement a socket connection in my apollo graphQL express server

I'm running an express based apollo graphQL server using apollo-server-express.
import express from 'express'
import cors from 'cors'
import server from './graphql/schema'
app.use(cors())
server.applyMiddleware({ app, path: '/graphql' })
app.listen(port, async () => {
if (process.env.NODE_ENV !== 'production') {
console.log('Listening on port ' + port)
}
})
export default app
Now I need to connect to some other applications from my client. Therefore he provides me with HL7 data. He told me to 'use a socket to get the HL7 data', which my application can use.
I just don't have a clue how to implement a socket connection at all.
Doing some researches brought me to libraries like socket.io, which should be used like this (for express):
const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
io.on('connection', () => { /* … */ });
server.listen(3000)
I don't understand how to implement the io in my existing code shown above.
I never used or implemented a socket connection at all, so I have very big understanding problems with that. Maybe the socket.io library is not the correct thing for my needs.
I do not have any knowlege about HL7 data, I think your another app has been writen by Java.
But, if you want to implement a socket.io server with apollo-server-express, just follow socket.io official document and attach a http server to express app and socket.io, then start your http server.
import express from 'express'
import cors from 'cors'
import GraphQLServer from './graphql/schema'
import socketIO from 'socket.io'
import http from 'http'
let app = express() // You missed this line ?
let httpServer = http.Server()
let io = socketIO(httpServer)
app.use(cors())
GraphQLServer.applyMiddleware({ app, path: '/graphql' })
httpServer.listen(port, async () => { // I don't see your `port`
if (process.env.NODE_ENV !== 'production') {
console.log('Listening on port ' + port)
}
})
io.on('connection', (socket) => {
console.log('A client connected', socket.id)
});
export default app

Categories