How to get port for node server in heroku - node.js

I have successfully deployed my react app to heroku -
http://goku-portfolio.herokuapp.com
inside the website there is a page called contact(you can see that on the navigation bar) where form appears which contains three fields, data of which is stored in mongodb. Problem that I am facing is after that entering the data when I click on the submit button it is redirecting to port 2000 of localhost that is something I have mentioned in the contact.js file because of which the backend runs successfully on my machine, but does not on other machines. Also after submission of data I want the user to redirect back to the homepage (i.e. the above link) which is also not working. kindly tell me what changes i would have have to make so that my app stops using the localhost ports.
P.S. - node server is running on port 2000 (file name db.js)
db.js
var express = require("express");
var path = require("path");
var bodyParser = require("body-parser");
var mongodb = require("mongodb");
var dbConn = mongodb.MongoClient.connect(
process.env.MONGODB_URI ||
"mongodb://user:pass#ds019633.mlab.com:19633/heroku_dtl69fwz"
);
var app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.resolve(__dirname, "src/components/contact.js")));
if (process.env.NODE_ENV === "production") {
app.use(express.static("src/build"));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "src", "build", "index.html"));
});
}
app.post("/post-feedback", function(req, res) {
console.log("something");
dbConn.then(function(db) {
delete req.body._id; // for safety reasons
db.collection("feedbacks").insertOne(req.body);
});
res.write("<html><body>");
res.write("Data received:\n" + JSON.stringify(req.body));
res.write("You will be redirected shortly to the home page");
res.write(
"<script>setTimeout(function(){ window.location.href = 'https://goku-portfolio.herokuapp.com'; }, 3000);</script>"
);
res.write("</body></html>");
res.send();
// res.sendFile("src/components/contact.js");
});
// app.get("/landingPage", function(req, res) {
// res.sendFile(__dirname + "src/components/contact.js");
// });
app.listen(process.env.PORT || 2000, process.env.IP || "0.0.0.0");
contact.js
import React, { Component } from "react";
class Contact extends Component {
state = {};
render() {
return (
<div className="container">
<div className="row bg-contact justify-content-center">
<div className="col-6">
<form
className="form-style"
method="POST"
action="http://localhost:2000/post-feedback"
>
<h1>Hola!</h1>
<h4>
{" "}
I am based out of Delhi and will be happy to assist you with
your request
</h4>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Email address</label>
<input
type="email"
name="email"
className="form-control"
id="exampleInputEmail1"
aria-describedby="emailHelp"
placeholder="Enter email"
></input>
package.json
{
"name": "resume",
"version": "0.1.0",
"private": true,
"dependencies": {
"body-parser": "^1.19.0",
"bootstrap": "^4.3.1",
"express": "^4.17.1",
"font-awesome": "^4.7.0",
"jquery": "^3.4.1",
"mongodb": "^2.2.33",
"popper.js": "^1.15.0",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-router-dom": "^5.0.1",
"react-scripts": "3.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"heroku-postbuild": "cd src && npm install && npm run build"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"description": "This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).",
"main": "index.js",
"devDependencies": {},
"keywords": [],
"author": "",
"license": "ISC"
}
I have changed the form action from https://localhost:3000/ to http://goku-portfolio.herokuapp.com/2000.

Related

when i deploy mern on heroku deploy problem in NODE_ENV

every thing is ok but when we write the code in this format
only show api call in formate of json or send but not show the react template
i can't undersatnd
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;
const NODE_ENV = process.env.NODE_ENV || "devlopment"
const path = require("path");
var cors = require('cors')
app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: true }));
app.get('/', (req, res) => {
res.json({
message: "Mern Deploy secces"
})
})
app.get('/sample', (req, res) => {
res.send("Hello Express");
})
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"))
app.get(" * ", (req, res) => {
res.sendFile(path.resolve(__dirname, "../client", "build", "index.html"))
});
console.log('production modde')
}
app.listen(port, () => {
console.log('server is running on 5000')
})
this is my node js file if i write the code in this formate
only show react js not show api request
index.js
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;
const NODE_ENV = process.env.NODE_ENV || "devlopment"
const path = require("path");
var cors = require('cors')
app.use(cors())
app.use(express.json())
app.use(express.urlencoded({ extended: true }));
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"))
app.get(" * ", (req, res) => {
res.sendFile(path.resolve(__dirname, "../client", "build", "index.html"))
});
console.log('production modde')
}
app.get('/', (req, res) => {
res.json({
message: "Mern Deploy secces"
})
})
app.get('/sample', (req, res) => {
res.send("Hello Express");
})
app.listen(port, () => {
console.log('server is running on 5000')
})
This is my React js File
import Raact, { useEffect ,useState } from 'react';
import './App.css';
import axios from 'axios';
function App() {
const [show, setshow] = useState("")
useEffect(()=>{
axios.get('/',)
.then((result)=>{
setshow(result.data.message)
}).catch((err)=>{
console.log(err)
})
},[])
return (
<div className="App">
<h1>Hello world</h1>
<h1>{show}</h1>
</div>
);
}
export default App;
client package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"#testing-library/jest-dom": "^5.11.10",
"#testing-library/react": "^11.2.6",
"#testing-library/user-event": "^12.8.3",
"axios": "^0.21.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"web-vitals": "^1.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:5000/"
}
package.json server
{
"name": "MERN-DEPLOY",
"version": "1.0.0",
"description": "",
"main": "index.js",
"engines": {
"node": "14.15.5",
"npm": "7.5.4"
},
"scripts": {
"start": "node server/index.js",
"backend": "nodemon server/index.js",
"fontend": "npm run front --prefix client",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix client ",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.17.1",
"nodemon": "^2.0.7"
}
}

React/Express App when deployed to Heroku only responds with index.html

I'm attempting to deploy my first react + express app. It works locally and runs both the front end and backed on port 8080. However when I deploy to heroku, the backend only responds with index.html. I've tried changing the scripts in package.json and the paths in server.js but I'm pretty stuck in terms of getting more information out of this error and what to try next. When I first deployed to heroku I received an H10 error, but then following an article recommendation I installed serve. That package resolved the H10 error, but the app doesn't respond with the json from the database. What am I missing here?
https://runtopia.herokuapp.com/
Package.json
{
"name": "runtopia",
"version": "0.1.0",
"private": true,
"dependencies": {
"#amcharts/amcharts4": "^4.9.26",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.5.0",
"#testing-library/user-event": "^7.2.1",
"express": "^4.17.1",
"lodash": "^4.17.15",
"moment": "^2.26.0",
"nedb": "^1.8.0",
"nodemon": "^2.0.4",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1",
"serve": "^11.3.2"
},
"scripts": {
"dev": "react-scripts start",
"start": "serve -s build",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"heroku-postbuild": "npm run build"
},
"proxy": "http://localhost:8080/",
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
server.js
const express = require('express');
const path = require('path')
const app = express();
const port = process.env.PORT || 8080;
const Datastore = require('nedb');
// console.log that your server is up and running
app.listen(port, () => console.log(`Listening on port ${port}`));
app.use(express.json());
// ADDED TO WORK FOR HEROKU
app.use(express.static(path.join(__dirname,'build')));
//retrieve data from database
app.get('/chartData', (request,response) => {
db.find({},(err,data) => {
if (err){
response.end();
return
}
response.json(data)
})
})
const db = new Datastore({filename:'./database.db', autoload: true});
app.post('/fitData', (request, response) => {
const fitData = request.body
fitData.map(week =>
{
console.log("logging week",week.weekYear)
db.update({'weekYear' : week.weekYear}, week, {upsert: true, multi: true}, function (){});
})
response.json({status: "this is the backend saying, got the lastest fitbit Data!"})
})
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.js
import React from 'react';
import Chart2 from './Chart';
import './App.css';
import moment from 'moment';
import _ from 'lodash';
class App extends React.Component{
constructor(props){
super(props)
this.state = {
fitData:[],
chartData: [],
}
this.grab = this.grab.bind(this);
this.queryDb = this.queryDb.bind(this)
}
//populates chart with data currently in db
componentDidMount(){
this.queryDb()
}
async post(){
const options = {
method: 'POST',
headers: {
'Content-Type' : 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(this.state.fitData)
}
const response = await fetch('/fitData', options);
const data = await response.json()
console.log(data)
await this.queryDb()
}
async queryDb(){
const response = await fetch('/chartData');
const dbData = await response.json()
let sorted = dbData.sort((a, b) => (a.date > b.date) ? 1 : -1)
this.setState({chartData:sorted})
}
render(){
return (
<div className="grid-container">
<div className="Top"></div>
<div className="Title">
<p className="runtopia">RUNTOPIA.</p>
<div>
<button className="big-button" onClick= {this.grab}>Get Data</button>
</div>
</div>
<div className="Weekly">
<Chart2 key={this.state.chartData} data={this.state.chartData} />
</div>
<div className="Bottom"></div>
</div>
);
}
}
export default App;

Google App Engine - Deploy different folder with the same app.yaml

I have this folder tree:
This is my actual app.yaml:
runtime: nodejs
env: flex
manual_scaling:
instances: 1
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
handlers:
- url: /api/.*
static_files: server/server.js
upload: server/server.js
- url: /
static_files: www/build/index.html
upload: www/build/index.html
- url: /
static_dir: www/build
But always, when I try to deploy the app with the following command: gcloud app deploy --stop-previous-version the process end whit this error:
Step #0: Application detection failed: Error: node.js checker: Neither "start" in the "scripts" section of "package.json" nor the "server.js" file were found.
The server/package.json is:
{
"name": "server",
"version": "1.5.2",
"engines": {
"node": "13.x"
},
"main": "server.js",
"description": "ConstaFAST server",
"scripts": {
"start": "node server.js"
},
"license": "MIT",
"dependencies": {
"#hapi/joi": "^16.1.7",
"base64-img": "^1.0.4",
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"generate-password": "^1.4.2",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.8.4",
"nodemailer": "^6.4.2",
"pdfkit": "^0.11.0",
"qrcode": "^1.4.4"
},
"devDependencies": {
"morgan": "^1.9.1"
}
}
and the www/package.json is:
{
"name": "www",
"version": "0.1.6",
"private": true,
"engines": {
"node": "13.x"
},
"dependencies": {
"#material-ui/core": "^4.8.2",
"#material-ui/icons": "^4.5.1",
"bootstrap": "^4.4.1",
"formik": "^2.1.1",
"jspdf": "^1.5.3",
"qrcode": "^1.4.4",
"qrcode.react": "^1.0.0",
"react": "^16.11.0",
"react-bootstrap": "^1.0.0-beta.14",
"react-dom": "^16.11.0",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.0",
"react-stripe-elements": "^6.0.1",
"yup": "^0.28.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
And at the end, the content of server/server.js is:
const express = require('express');
const app = express();
const path = require('path');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
require('dotenv').config()
const agencyRoutes = require('./api/routes/agency');
const companyRoutes = require('./api/routes/company');
const userRoutes = require('./api/routes/user');
const qrcodeRoutes = require('./api/routes/qrcode');
const vehicleRoutes = require('./api/routes/vehicle');
const writerRoutes = require('./api/routes/writer');
const port = process.env.PORT || 8080;
mongoose.connect(String(process.env.DB_CONNECT), {
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true
}, () => console.log('Connect to the database'));
mongoose.Promise = global.Promise;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use( (req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://constafast.cf');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
res.header('Connection', 'Keep-Alive');
if ( req.method === 'OPTIONS' ) {
res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');
return res.status(200).json({});
}
next();
});
app.use(express.static(path.resolve(__dirname, '../www', 'build')));
app.use('/api/agency', agencyRoutes);
app.use('/api/company', companyRoutes);
app.use('/api/user', userRoutes);
app.use('/api/qrcode', qrcodeRoutes);
app.use('/api/vehicle', vehicleRoutes);
app.use('/api/writer', writerRoutes);
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '../www', 'build', 'index.html'));
});
app.use( (req, res, next) => {
const error = new Error('Not found');
error.status = 404;
next(error);
});
app.use( (error, req, res, next) => {
res.status(error.status || 500);
res.json({
error: {
message: error.message
}
});
});
app.listen(port, () => console.log(`Server up and running on port ${port}`));
module.exports = app;
I see no way of specifying the location of the package.json and server.js files, neither in the app.yaml reference, nor in the gcloud app deploy reference, so I'd guess it has to be located side-by-side with the app.yaml file (as seen in the sample app).
The error you see could very well be caused by the deployment command not finding the mentioned files where it expects them.
In other words you'd have to move/copy the app.yaml file in the server directory. It might be possible to symlink the file to avoid actual code duplication if you want to also deploy from another directory (it works for the standard environment, but I'm not certain the same is true for the flexible one).
Side note: I don't think your static handlers (which I suspect could also be the reason for which you seek such app structure) will be working - there's no mention of such capability in the app.yaml reference or in the Serving Static Files section. Maybe you accidentally looked at the standard environment docs? (check How to tell if a Google App Engine documentation page applies to the 1st/2nd generation standard or the flexible environment) If you drop the handlers there's very little left in the app.yaml file - a rather low re-use value for the effort to do so (if even possible). I'd just keep things simple and stick to the recommended way.

Deploy React with Heroku

Hi i'm trying to deploy my project with heroku but it's impossible i don't understand
I already did like that on other project but this time it doesn't works in my server.js i have this code :
const express = require("express");
const graphqlHTTP = require("express-graphql");
const cors = require("cors");
const schema = require("./schema");
const path = require("path");
const app = express();
//allow Cross origin
app.use(cors());
app.use(
"/graphql",
graphqlHTTP({
schema,
graphiql: true
})
);
app.use(express.static('public'));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, 'public', 'index.html'));
});
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
In my app.js who is in my Client folder i modify uri for AplolloClient :
import React from 'react';
import './App.css';
import Logo from "./logo.png";
import Matchs from './components/Matchs'
import MatchDetail from './components/MatchDetail'
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "#apollo/react-hooks";
import { BrowserRouter as Router, Route } from "react-router-dom";
const client = new ApolloClient({
uri: "/graphql"
});
function App() {
return (
<ApolloProvider client={client}>
<Router>
<div className="container">
<img
src={Logo}
alt="Nba App"
style={{ width: 300, display: "block", margin: "auto" }}
/>
<Route exact path="/" component={Matchs} />
<Route exact path="/match/:gameId" component={MatchDetail} />
</div>
</Router>
</ApolloProvider>
);
}
export default App;
in my package.json from my client folder i add a proxy :
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"#apollo/react-hooks": "^3.1.3",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.3.2",
"#testing-library/user-event": "^7.1.2",
"apexcharts": "^3.15.5",
"apollo-boost": "^0.4.7",
"classnames": "^2.2.6",
"graphql": "^14.6.0",
"lodash.flowright": "^3.5.0",
"react": "^16.12.0",
"react-apexcharts": "^1.3.6",
"react-apollo": "^3.1.3",
"react-dom": "^16.12.0",
"react-icons": "^3.9.0",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build && mv build ../public",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:5000"
}
And i made a script to build and move in public/build
But when i deploy in heroku i have always
VM165:1 POST http://localhost:4000/graphql net::ERR_CONNECTION_REFUSED
But i don't know where he take this Url because i think i change all places where it could be problematic
Thanks a lot

(Node.js and React) Cannot POST / when submitting form

I'm trying to create a form with Node.js and React where you can input your email to submit it to a Mailchimp newsletter, but when I click submit, I get a "Cannot POST /" error.
This is server.js
const bodyParser = require('body-parser');
const favicon = require('serve-favicon');
const express = require('express');
const app = express();
app.use(express.static(__dirname + '/client/public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(favicon(__dirname + '/public/favicon.ico'));
app.listen(process.env.PORT, function() {
console.log("Listening to the application");
});
app.get('/', (req, res) => {
res.send("res");
});
app.post('/', (req, res) => {
sendEmailToMailchimp(req.body.email);
console.log(req.body.email);
});
function sendEmailToMailchimp(email){
console.log("Sending " + email + " to Mailchimp.");
var request = require("request");
var options = { method: 'POST',
url: 'https://us18.api.mailchimp.com/3.0/lists/f9c3130fc4/members',
headers:
{ 'Postman-Token': 'f6c16b72-09b7-48f2-926b-b156a428c67b',
'Cache-Control': 'no-cache',
Authorization: 'Basic YW55c3RyaW5nOmNiNTQyYzA1NWVmMjY1ZTI4Y2I0ZDk0NmRhZmM5MmYzLXVzMTg=',
'Content-Type': 'application/json' },
body: { email_address: email, status: 'subscribed' },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
//console.log(body);
});
}
This is package.json
{
"name": "myapp",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js",
"server": "nodemon server.js",
"client": "npm start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""
},
"keywords": [
"example",
"heroku"
],
"author": "",
"license": "MIT",
"dependencies": {
"body-parser": "^1.18.3",
"concurrently": "^3.6.1",
"express": "^4.16.3",
"jquery": "^3.3.1",
"nodemon": "^1.18.3",
"request": "^2.87.0",
"serve-favicon": "^2.5.0"
},
"engines": {
"node": "8.11.1"
}
}
This is App.js in my client React app. The input field for the name still isn't meant to do anything yet, just the email.
import React, { Component } from 'react';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<form className="newsletterSignup" action="/" method="post">
<label>NAME</label>
<input id="nameInput" className="infoInput inlineInput" name="userName" placeholder="John Ipcus" type="text" required></input>
<label>EMAIL ADDRESS</label>
<input id="emailInput" className="infoInput inlineInput" name="userEmailAddress" placeholder="joe#shmoe.com" type="text" required></input>
<input id="signUpBtn" value="SUBMIT" type="submit"></input>
</form>
</div>
);
}
}
export default App;
And this is the package.json in the client React app
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-scripts": "1.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"proxy": {
"/": {
"target": "http://localhost:5000",
"secure": "false"
}
}
}
Also if it helps mentioning, I'm going to deploy it on Heroku.
Thanks
Edit: the browser console displays "Failed to load resource: the server responded with a status of 404 (Not Found)"
Do you use webpack-dev as react development server?
If so you need to setup proxy there, webpack.config.js like:
module.exports = setup({
context: __dirname,
entry: './app.js',
devServer: {
proxy: {
'/api': 'http://127.0.0.1:50545'
}
}
});

Resources