I'm new to react and node and I'm trying to build a simple app to retrieve stock prices.
I'm able to reach my server route that I want but I'm getting a FetchError: invalid json response body from my server, what does this mean? How should I properly fetch an external api in my express route and send that data as a response?
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
state = {
response: '',
symbol: '',
};
handleSubmit = async e => {
e.preventDefault();
let apiURL = `/stocks/${ this.state.symbol }/price`
fetch(apiURL)
.then(res => res.json())
.then( (result) => {
this.setState({
response: result
})
})
};
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
</header>
<form onSubmit={this.handleSubmit}>
<input
type="text"
value={this.state.symbol}
onChange={e => this.setState({ symbol: e.target.value })}
/>
<button type="submit">Submit</button>
</form>
<p>{this.state.response}</p>
</div>
);
}
}
export default App;
server.js
const express = require('express')
const path = require('path')
const bodyParser = require('body-parser')
const fetch = require('node-fetch');
const app = express()
const port = process.env.PORT || 5000
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
// API routes
app.get('/stocks/:symbol/price', (req, res) => {
const token = 'pk_5f69bda1e3074237a9d2e844a3dafbff'
const symbol = req.params.symbol
const apiURL = `https://sandbox.iexapis.com/stable/stock/${symbol}/price?token=${token}`
fetch(apiURL)
.then(res => res.json())
.then(data => {
res.send({ data })
})
})
app.listen(port, () => console.log(`Listening on port ${port}`))
package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.19.0",
"body-parser": "^1.18.3",
"express": "^4.16.4",
"node-fetch": "^2.6.0",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-scripts": "0.9.x"
},
"devDependencies": {
"concurrently": "^4.0.1",
"nodemon": "^1.9.2",
"ws": "3.3.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"client": "yarn start",
"server": "nodemon server.js",
"dev": "concurrently --kill-others-on-fail \"yarn server\" \"yarn client\""
},
"proxy": "http://localhost:5000/"
}
Related
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"
}
}
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;
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
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.
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'
}
}
});