Meteor - callback executing twice - reactjs

I have this Meteor app that sends data to an api then uses the data sent back in the website. However, when I call the function that gets the api data, uploadToCloudinary() which has a callback, I find it running twice. One of the documents get inserted correctly with the correct information and one is missing the res.data.secure_url. Am I not doing the callback thing right or is it because it is non-blocking code, so I think(correct me if I am wrong) that when the imageURL.push function executes, it cannot find a res so it goes and does the other code first and then when it finds the res it pushes it and creates another document.
import { Meteor } from "meteor/meteor"
import React from "react";
import { withRouter, Link } from "react-router-dom";
import SimpleSchema from "simpl-schema";
import axios from "axios"
import { SubjectRoutes } from "./subjectRoutes/subjectRoutes";
import "../methods/methods";
import Menu from "./subComponents/Menu";
class AddNote extends React.Component{
constructor(props){
super(props);
this.state = {
message: "",
loginMessage: (<div></div>),
urls: []
};
}
renderSubjects(subjects){
return subjects.map((item) => {
return <option key={item}>{item}</option>
})
}
componentWillMount() {
Meteor.subscribe('user');
}
addNote(e){
e.preventDefault();
let title = this.refs.title.value;
let subject = this.refs.subject.value;
let description = this.refs.description.value;
let allUrls = [this.refs.imageURL.value].concat(this.state.urls);
let imageURL = allUrls.filter(function(entry) { return entry.trim() != ''; });
let userId = Meteor.userId();
let userEmail = Meteor.user().emails[0].address;
let createdAt = Date.parse(new Date());
let unit = this.refs.unit.value;
let file = this.refs.fileInput.files[0];
if(!Meteor.userId()){
this.setState({
message: "You need to login before you can add a note",
loginMessage: <Link to="/login">Login</Link>
})
throw new Meteor.Error(400, "User is not signed in.")
}
if(title && subject && description && unit){
if(imageURL.length == 0 && file == undefined){
this.setState({ message: "You need to enter an image." })
return;
}
console.log(imageURL.length, file)
if(imageURL){
let noteInfo = { title, subject, description, imageURL, userId, userEmail, createdAt, unit };
Meteor.call("notes.insert", noteInfo, (err, res) => {
if(err){
this.setState({ message: "Please enter a valid image URL." });
}else{
this.props.history.push("/")
}
})
}
if(file){
let noteInfo = { title, subject, description, imageURL, userId, userEmail, createdAt, unit };
this.uploadToCloudinary(file, (err, res) => {
imageURL.push(res.data.secure_url);
Meteor.call("notes.insert", noteInfo, (err, res) => {
//problem .......inserting 2 docs, one empty and one with proper data
console.log("CALLED")
if(err){
this.setState({message: err.reason});
console.log(err);
}else{
this.props.history.push("/")
}
})
});
}
}
}
addLink(){
let file = this.refs.fileInput.files[0];
if(this.refs.imageURL.value || file != undefined){
if(this.state.urls.length < 10){
if(!this.state.urls.includes(this.refs.imageURL.value)){
const URLSchema = new SimpleSchema({
imageURL:{
type:String,
label:"Your image URL",
regEx: SimpleSchema.RegEx.Url
}
}).validate({ imageURL:this.refs.imageURL.value })
let urls = this.state.urls.concat([this.refs.imageURL.value]);
this.setState({ urls });
this.refs.imageURL.value == "";
}else{
this.setState({ message: "You already inserted this note." })
}
}else{
this.setState({ message: "Only allowed 10 notes per upload. "})
}
}else{
this.setState({ message: "Please enter a note." })
}
}
uploadToCloudinary(file, callback){
const CLOUDINARY_URL = "MY_CLOUDINARY_URL";
const CLOUDIARY_UPLOAD_PRESET = "MY_CLOUDIARY_UPLOAD_PRESET"
let formData = new FormData();
formData.append("file", file);
formData.append("upload_preset", CLOUDIARY_UPLOAD_PRESET)
axios({
url: CLOUDINARY_URL,
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
data: formData
}).then(function(res){
callback(new Meteor.Error(400, "Error, cannot connect to cloudinary."), res);
}).catch(function(err){
console.log(err);
})
console.log(file);
}
render(){
return(
<div>
<form onSubmit={this.addNote.bind(this)}>
<Menu />
<p>*Just a friendly reminder: If you cannot read the note yourself,
others cannot as well. Please make sure your notes are clear and
easy to read.*</p>
<h1>Add a note</h1>
<br />
<input className="addNote-input" id="title" ref="title" type="text" placeholder="Title" autoComplete="off" />
<br />
<select ref="subject">
<option selected disabled value="">Choose a subject</option>
{this.renderSubjects(SubjectRoutes)}
</select>
<br />
<input className="addNote-input" id="description" ref="description" placeholder="Description Here..." autoComplete="off" />
<br />
<Link to="/questions">What is this?</Link><br />
<div className="inline full">
<div className="left">
<input id="imageUrl" className="addNote-input insert-link" ref="imageURL" placeholder="Enter image URL here" autoComplete="off" />
</div>
or
<div className="right">
<input className="addNote-input inline" type="file" ref="fileInput" onChange={this.readImage} id="fileInput" autoComplete="off"/>
</div>
<div className="full inline-block">
<span onClick={this.addLink.bind(this)} id="addLink">+</span>
<span>({this.state.urls.length})</span>
</div>
</div>
<input className="addNote-input" placeholder="Subject Unit" type="text" ref="unit" autocomplete="off" />
<br />
<button>Add Note</button>
<br />
<div className="alert alert-danger">Error: {this.state.message}</div>
<br />
{this.state.loginMessage}
</form>
</div>
)
}
}
export default withRouter(AddNote);
PS the function uploadToCloudinary() just receives data as an argument and sends it to an api then puts it into a callback to return an object. And also the console.log("CALLED") is only executed once which is really confusing to me since it is creating two documents so it should be running twice. Thanks in advance!

You're calling notes.insert method twice in addNote():
In if (imageURL) { ... }
In if (file) { ... } — this one is calling uploadToCloudinary first and adds secure_url into imageURL.

Related

MongoDB + React - Obtain a document from db based on a query I am passing

I am trying to access a document from my MongoDB Atlas db that contains a specific key, based on a query I am passing in the fetch. I've followed the guides on the backend setup from MongoDB, it's all working, I'm connected to it, and now here's what I'm trying to do:
Documents look like this:
{
invitationCode: string;
name: string;
numberOfPeople: number;
specialMentions: string;
confirmed: boolean;
}
In the frontend, there's only one input at first, where the user should be entering his invitation Code. Once he clicks on the button, a request should be made to the BE, sending the value he entered. The BE should look through the documents and find the document that contains the invitationCode mathing with the input (The invitation codes are all unique). After the BE identified the document, it should be sent back to the frontend, so I can juggle with it here (display the name of the person, show the other 3 fields, etc.)
Here's what I have so far:
in my record.js file (backend):
const express = require("express");
const recordRoutes = express.Router();
const dbo = require("../db/conn");
const ObjectId = require("mongodb").ObjectId;
recordRoutes.route('/record/invitations').post(function (req, res) {
let db_connect = dbo.getDb();
let myquery = req.body.invitationNumber;
console.log('MYQUERY:', myquery);
db_connect
.collection('records')
.findOne({zzceva: myquery}, function (err, result) {
if (err) throw err;
console.log('RESULT FROM BE', result);
res.send(result);
})
console.log('QUERY:', myquery);
})
and in the frontend I have this logic:
const onSubmit = useCallback(async (e) => {
e.preventDefault();
if (personEnteredCode) {
const newPerson = { ...form };
await fetch("http://localhost:5000/record/add", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(newPerson),
})
.catch(error => {
window.alert(error);
return;
});
setForm({ invitationNumber: "", numberOfPeople: "", specialMentions: "" });
navigate("/");
console.log('newPerson:', newPerson);
} else {
// THIS IS WHAT DOES NOT WORK >>>>>>>>>>>>>>>>>>>>>>>>>>>
// I AM TRYING TO SEND THE invCode back to the BE
const invCode = form.invitationNumber;
await fetch("http://localhost:5000/record/invitations", {
method: 'POST',
body: JSON.stringify(invCode),
})
.then((response) => {
console.log('THE RESPONSE IS:', response);
setCurrentPerson(response);
})
.catch(error => {
window.alert(error);
return;
})
.finally(() => setPersonEnteredCode(true))
}
// When a post request is sent to the create url, we'll add a new record to the database.
}, [form, navigate, personEnteredCode])
return (
<div className="confirm-form">
<form onSubmit={onSubmit}>
<div className="form-group">
<label htmlFor="invitationCode">Cod invitație:</label>
<input
type="text"
className="form-control"
id="invitationCode"
value={form.invitationNumber}
onChange={(e) => updateForm({ invitationNumber: e.target.value })}
/>
</div>
{!personEnteredCode && <input type={'submit'} value={'OK'}/>}
{personEnteredCode && <div className="form-group">
<label htmlFor="numberOfPeople">Număr persoane:</label>
<input
type="number"
className="form-control"
id="numberOfPeople"
value={form.numberOfPeople}
onChange={(e) => updateForm({ numberOfPeople: e.target.value })}
/>
</div>}
{personEnteredCode && <div className="form-group">
<div className="form-check form-check-inline">
<label htmlFor="specialMentions">Mențiuni speciale:</label>
<input
type="text"
className="form-control"
id="specialMentions"
value={form.specialMentions}
onChange={(e) => updateForm({ specialMentions: e.target.value })}
/>
</div>
</div>}
{personEnteredCode &&<div className="form-group">
<input
type="submit"
value="Confirmă"
className="btn btn-primary"
/>
</div>}
</form>
</div>
);
}
After many different tries, now the response I'm getting is 200 (not 404 not found or 500 like the first tries), but on the response object, I don't see the information I need, instead this is how a console.log looks like:
HUGE thanks in advance for any kind of guidance or help you could provide. I'm trying to understand what I'm doing wrong.
The issue is that you're logging the fetch response and not the data in the response body (so congrats! you're getting a response!).
The fetch response has a couple of different methods that you can use to read the data in the body. Depending on the type of data your API is returning, you'll use the appropriate method (.json, .text, .blob, etc.). These methods return a promise meaning they are asynchronous. Here's how you might modify your code:
fetch("http://localhost:5000/record/invitations", {
method: 'POST',
body: JSON.stringify(invCode)
})
.then((response) => {
return response.json()
})
.then((data) => {
//now you've got the data to put in state
setCurrentPerson(response);
})
.catch(error => {
window.alert(error);
return;
})
}
I can see that in your Express route, you're using res.send(result). You'll probably want to change that to: res.json(result). Both behave the same if you pass an object or array, but res.json() will explicitly convert your results to JSON.
Also, you didn't ask about it, but generally, you wouldn't use POST for this route. In REST, this would be a GET route and you'd generally pass the data as a param or querystring to your API.

React login form loop isn't re-rendering DOM

I'm trying to make a login component and I think my issue is with React not re-rendering the DOM in my browser but I'm not sure why
If I leave the password field blank when I press the main 'Login' button in my form it will render the alert / warning message .. I can then click this message to dismiss it which is exactly what I want
If I were to repeat the process I would expect the message to be re-rendered and the DOM element reintroduced, however this is not the case - I can see that the loop is being run, I am getting all of the console logs with the correct values, however the loop does not seem to run the 'return' part of my if statement on the second try (in the code below I've added 'this return doesn't re-render' to the console log before that return) - here's my code
Apologies for the large code snippet but I felt it was all relevant for this question
class LoginForm extends Component {
constructor() {
super();
this.state = {
email: "",
password: "",
errors: [],
};
this.onLoginClick = this.onLoginClick.bind(this);
}
onLoginClick() {
const username = this.state.email.trim();
const password = this.state.password.trim();
let errors = [];
console.log("Login press")
if (!EMAIL_REGEX.test(username)) {
errors.push(error_user);
console.log("Username error")
}
if (password === "") {
errors.push(error_pass);
console.log("Password is blank")
}
if (errors.length === 0) {
this.props.onLoginClick(username, password);
if (this.props.loginStatus === login_f) {
errors.push(error_cred);
}
}
this.setState({
errors: errors,
});
console.log("Here are the errors", errors)
}
handleEmailChange = (e) => {
this.setState({ email: e.target.value });
};
handlePasswordChange = (e) => {
this.setState({ password: e.target.value });
};
clearAlertsHandler() {
console.log("Clear alerts")
document.getElementById("misMatch").remove()
}
render() {
let updatedErrors = [...this.state.errors];
return (
<fieldset>
{updatedErrors.map((errorMessage, index) => {
if (errorMessage === error_cred) {
console.log("error_cred match", error_cred, errorMessage)
return (
<button key={index} id={"match"}>{errorMessage} - click to clear</button>
);
} else {
console.log("error_cred mismatch - this return doesn't re-render", error_cred, errorMessage)
return (
<button key={index} id={"misMatch"} onClick={(e) => this.clearAlertsHandler(e)}>{errorMessage} - click to clear</button>
);
}
})}
<label className="text-uppercase">Username</label>
<input
name="email"
type="text"
value={this.state.email}
placeholder="username"
onChange={this.handleEmailChange}
/>
<label className="text-uppercase">Password</label>
<input
className="mb20"
name="password"
type="password"
value={this.state.password}
placeholder="••••••••••"
onChange={this.handlePasswordChange}
/>
<button name="submit" className="primary mb20" onClick={this.onLoginClick}>
Login
</button>
</fieldset>
);
}
In my opinion, React doesn't know that error array changed if you don't clear it.
I think you should do something like this:
clearAlertsHandler() {
console.log("Clear alerts")
this.setState({
errors: [],
});
document.getElementById("misMatch").remove()
}

Save innerHTML data and input data to firebase

I have this code where I want to save data to firebase. I want to be able to save selected meeting to firebase along with input in form. I am new to react and stuck at the moment to get further with my code so some suggestions what I can do would be much appreciated.
This is how my app looks like and with error
I have conected firebase and I am able to push up data but cant save data from my properties as handleClick..
Error when I try to submit form
import './App.css';
import firebase from 'firebase';
const uuid = require('uuid');
class App extends Component {
constructor(props) {
super(props);
// gör strängar av state
this.state = {
uid: uuid.v1(),
meeting:'',
name:'',
email:'',
};
// binder propertys till click funktion
this.handleClick = this.handleClick.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.inputData = this.inputData.bind(this);
// kopplar databas
var config = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: ""
};
firebase.initializeApp(config);
// console.log(firebase);
// skapar databasen lokalt med referens ref
var database = firebase.database();
var ref = database.ref('meeting');
// variabel data med sträng id
var data ={
id: '',
}
// Pushar upp data till databas
ref.push(data);
}
// hämtar klick för mötes knappar och skriver ut text i knappar
handleClick = (e) =>{
console.log(e.target.innerHTML);
alert('Du har valt ett möte');
}
// hämtar API för olika möten
componentDidMount(){
fetch('http://www.mocky.io/v2/5c9cdca03300004d003f2151')
.then(res => res.json())
.then(json => {
let meetings = []
json.forEach(meeting => {
if(new Date(meeting.startDate).getDay() !== new Date(meeting.endDate).getDay()){
let day1 = {
activity:meeting.activity,
location:meeting.location,
startDate:meeting.startDate,
}
let day2 = {
activity:meeting.activity,
location:meeting.location,
endDate:meeting.endDate,
}
meetings.push(day1,day2)
}else{
meetings.push(meeting)
}
});
console.log(meetings)
this.setState({
isLoaded:true,
items: meetings,
})
});
// import firebase och ref sträng
firebase
.database()
.ref(`Newdata/${this.state.uid}`)
.on('value', snap => console.log('from db', snap.val()));
}
// hämtar ny data
handleChange(e){
this.setState({
name: e.target.name});
}
// hämtar ref och skriver ut sträng med set till firebase
handleSubmit(e){
alert('Er bokning är bekräftad: ' + this.state.value);
console.log('Du har bekräftat er bokning')
e.preventDefault();
firebase
.database()
.ref(`Newdata/${this.state.uid}`)
.set({
meeting: this.state.meeting,
name: this.state.name,
email: this.state.email,
})
.catch(error => console.log(error));
}
// knyter input text till property
inputData (_e){
const meeting = this.refs.meeting1.value;
const name = this.refs.name1.value;
const email = this.refs.email1.value;
this.setState({ meeting, name, email});
}
render() {
var { isLoaded, items } = this.state;
if (!isLoaded){
return <div>Loading...</div>;
}
else {
return (
<>
<div className="App">
<div className="AppHeader">
<h1>Boka ditt möte nedan</h1>
</div>
<ul>
{items.map((item,i) => (
<li key={i}>
{/* kopplar handleClick till onChange*/}
<button onClick={(e) => this.handleClick(e)} onChange={this.inputData} ref="meeting1" className="select">
{item.activity}<br/>
Starttid: {item.startDate}<br/>
Sluttid: {item.endDate}<br/>
Plats: {item.location}<br/>
</button>
</li>
))}
</ul>
</div>
<div className="selectedMeeting">Fyll i dina uppgifter och bekräfta</div>
<form onSubmit={this.handleSubmit} className="bookingSection">
<label>
Name:
<input type="text" value={this.state.name} onChange={this.inputData}
ref="name1"/>
</label>
<label>
E-mail:
<input type="text" value={this.state.email} onChange={this.inputData}
ref="email1"/>
</label>
<input className="confirm" type="submit" value="Bekräfta" />
</form>
<div className="viewSelect"></div>
</>
);
}
}
}
export default App;
I get an error when I try to save the meeting, name, email to firebase.
By default the database is only accessible to authenticated users.
'rules': {
'.read': 'auth != null',
'.write': 'auth != null'
}
You have to define the rules on the Firebase console
You can allow to read or write the databse to everyone under development and then if needed add more rules (I suggest you to get familiar with the firebase rules):
'rules': {
'.read': true,
'.write': true
}
This should solve your issue for now.
Also, if you are new to React, I suggest you to learn to use Redux and combine it with React Redux Firebase, these will help you a lot alongside with React.
You can find the full explanation to this problem in Stackoverflow answer . It is also explained how to handle proper sign-In correctly.

Function CollectionReference.add() requires its first argument to be of type object, but it was: undefined

I want to store the image in firebase storage and pass its URL reference in firestore. So I'm able to upload an image in storage but unable to pass the image URL reference in cloud firestore.
import React , {Component} from 'react';
import fire from './../fire'
import Uploadimg from './Uploadimg'
class Adproduct extends Component{
geturl = (imurl) =>{
this.setState({
img:imurl
});
}
submit = e =>{
e.preventDefault()
var db= fire.firestore();
db.settings({
timestampsInSnapshots: true
});
db.collection('newproducts').add(this.State)
.then(res =>{
console.log(res.id)
this.props.submit()
})
.catch(err =>{
console.log('something went wrong',err)
})
}
takedata = e =>{
this.setState({
[e.target.name]: e.target.value
});
}
constructor(props){
super(props);
this.state ={
name:'',
productdetails:'',
size:'',
}
}
render() {
return (
<div className="container w3-padding">
<div className="row w3-padding">
<div className="col-md-6 w3-padding">
<h3 className="w3-tag w3-padding w3-center">Add New</h3>
<form className="w3-container" onSubmit={this.submit}>
<label className="w3-text-blue"><b>Name</b></label>
<input className="w3-input w3-border" type="text" name="name" value={this.state.name} onChange={this.takedata} required/>
<label className="w3-text-blue"><b>productdetails</b></label>
<input className="w3-input w3-border" type="text" name="productdetails" value={this.state.productdetails} onChange={this.takedata} required/>
<label className="w3-text-blue"><b>size available</b></label>
<input className="w3-input w3-border" type="text" name="size" value={this.state.size} onChange={this.takedata} required/>
<br/>
<Uploadimg geturl={this.geturl} />
<br/>
<button className="w3-btn w3-blue">Add</button>
</form>
</div>
</div>
</div>
);
}
}
export default Adproduct;
If the accepted answer doesn't help you, you might be having the same issue I was having.
I solved this by using the typescript spread operator:
add(wizard: Wizard): Promise<DocumentReference> {
return this.wizardCollection.add({...wizard});
}
Hope this helps you.
use
db.collection('newproducts').add({...this.State})
instead of
db.collection('newproducts').add(this.State)
it can happen if you forgot to create database in the project...
Its happen to me - I copy the project secret key - but forgot to actually create database in the project.... after I create the DB - it solved...
It simply works for me.
Go in Database -> Rules ->
Change allow read, write: if false; to true;
It can happen because either you have not created any database or have no permission to read/write on the database from Under Rules tab i.e,
{
"rules": {
".read": true,
".write": true
}
}
You should create the Firestore database, allow the read, write rules, and configure it to your project. Then you can use the spread operator as below to save.
saveStudent(student: Student) {
return new Promise<Student> ((resolve, reject) => {
this.fireStore.collection('students').add({...student}).then(res => {}, err => reject(err));
});
}
From the documentation
To use a custom class, you must define a FirestoreDataConverter function for your class. For example:
class City {
constructor (name, state, country ) {
this.name = name;
this.state = state;
this.country = country;
}
toString() {
return this.name + ', ' + this.state + ', ' + this.country;
}
}
// Firestore data converter
var cityConverter = {
toFirestore: function(city) {
return {
name: city.name,
state: city.state,
country: city.country
}
},
fromFirestore: function(snapshot, options){
const data = snapshot.data(options);
return new City(data.name, data.state, data.country)
}
}
Call your data converter with your write operation:
// Set with cityConverter
db.collection("cities").doc("LA")
.withConverter(cityConverter)
.set(new City("Los Angeles", "CA", "USA"));

Fetching express data from react

I'm trying to create a simple register form by preparing the data in the back end, and inserting the data from my react form into the mysql database. I know that there are many tutorials out there for how to do this however, I'm trying to do it by myself my own way.
Therefore, when I try to fetch the data from the back end, it throws me an error. saying the resource isn't found. On my server, when I put in the path to view the data it informs me that the path isn't found even though I required it?
Also, I believe I'm a little confused on the process of how data can be fetched over relative paths. How is this possible if React is using a different port than what the server is using? Does the fetch for relative paths go purely based on your folder location of the data you're trying to fetch?
For react the port I'm using is 3000
for and for the server I'm using 5000
Here is my code:
Model:
var db = require('../dbconnection');
var register = {
registerAuth: function(data, callback){
db.query("insert sanames (id, fullName, email, confirmEmail, password, confirmPassword) values(newid(), '"+data.fullName+"', '"+data.email+"', '"+data.confirmEmail+"', '"+data.password+"', '"+data.confirmPassword+"')")
}
}
// db.query('insert sanames (id, fullName, email, confirmEmail, password, confirmPassword, dateAdded) values(newid(), "'data.fullName'", "'data.email'", "'data.confirmEmail'", "'data.password'", "'data.confirmPassword')")',callback)
module.exports = register;
Route:
var express = require('express');
var router = express.Router();
var register = require('../models/register');
router.post('/:registerAuth', function(req, res, next) {
register.registerAuth(req.body,function(err, rows) {
if (err) {
res.json(err);
} else {
res.json(rows);
}
});
});
module.exports = router;
App (Server):
var express = require('express');
var bodyParser = require('body-parser');
var mysql = require('mysql');
var path = require('path');
var port = 5000;
var app = express();
//app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use('/public', express.static(__dirname + "/public"));
var Register=require('./routes/register');
app.use('/register', Register);
app.listen(port, () => {
console.log(`Server is listening on ${port}`);
});
// app.get('/test', (req, res) => {
// res.send('Test');
// })
View:
import React from 'react';
import ReactDOM from 'react-dom';
import Header from '../../common/header';
class Register extends React.Component {
constructor(props){
super(props);
this.state = {
fullName: "",
email: "",
confirmEmail: "",
password: "",
confirmPassword: "",
formErrors: "",
success: ""
}
}
onChange(e){
this.setState({
[e.target.name]: e.target.value
});
};
onSubmit(e) {
// if(this.state.fullName !== '' || this.state.email || '' || this.state.confirmEmail !== '' || this.state.password !== '' || this.state.confirmPassword !== ''){
// if(this.state.password !== this.state.confirmPassword) {
// //console.log('passwords do not match');
// this.setState({
// formErrors: 'passwords do not match'
// });
// e.preventDefault();
// }
// if(this.state.email !== this.state.confirmEmail) {
// //console.log('email address must match');
// this.setState({
// formErrors: 'both email address must match'
// });
// e.preventDefault();
// }
// } else {
// //console.log('please fill out all fields');
// this.setState({
// formErrors: 'please fill out all fields'
// });
// e.preventDefault();
// }
e.preventDefault();
var data = {
fullName: this.state.name,
email: this.state.email,
confirmEmail: this.state.confirmEmail,
password: this.state.password,
confirmPassword: this.state.confirmPassword
}
fetch("/register", {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then(function(response){
if(response.status >= 400) {
throw new Error("Bad response from server");
}
return response.json();
}).then(function(data){
console.log(data);
if(data == "success"){
this.setState({sucess: 'User has been successfully registered'});
}
}).catch(function(err){
console.log(err);
});
}
render(){
return (
<div className="background-video">
<Header />
<div className="login-container">
<div className="login-wrapper">
<div className="loginfields-wrap">
{this.state.formErrors !== '' ? <div className="alert alert-danger" role="alert">{this.state.formErrors}</div> : ''}
<form
onSubmit={e => this.onSubmit(e)}
autoComplete="off"
method="POST"
action="/registeruser"
>
<input
type="text"
name="fullName"
className="form-control"
placeholder="First/Last Name"
value={this.state.fullName}
onChange={e => this.onChange(e)}
/>
<input
type="email"
name="email"
className="form-control"
placeholder="Email"
value={this.state.email}
onChange={e => this.onChange(e)}
/>
<input
type="email"
name="confirmEmail"
className="form-control"
placeholder="Confirm Email"
value={this.state.confirmEmail}
onChange={e => this.onChange(e)}
/>
<input
type="password"
name="password"
className="form-control"
placeholder="Password"
value={this.state.password}
onChange={e => this.onChange(e)}
/>
<input
type="password"
name="confirmPassword"
className="form-control"
placeholder="Confirm Password"
value={this.state.confirmPassword}
onChange={e => this.onChange(e)}
/>
<button type="submit" className="btn btn">Register</button>
</form>
</div>
</div>
</div>
</div>
);
}
}
export default Register;
I hope my answer helps, its a bit tough to answer.
First thing I did was change the fetch to the following:
fetch("http://localhost:5000/register"
At first attempt I got a CORS issues, so I installed the npm package:
https://www.npmjs.com/package/cors
You can setup a proxy in your package JSON file which will help connect your React App to the express server - this is one way of how the app will connect to your express server - Its not that they are in the same folder, you can setup a server in a different folder and still connect to it, try it out - if it helps with understanding it more clearly.
"proxy": "http://localhost:5000"
Hope this helps

Resources