Having issues connecting to express backend with React - reactjs

Trying to set up a register form using react and then sending the form to my express backed to create the user. The request is getting to the back-end but none of the form data is there.
When i console.log the request body and params, only an empty object gets returned
Here is my react register code
import React from 'react'
class Register extends React.Component {
state = {
name: "",
username: "",
password: ""
}
handleChange = event => {
const { name, value } = event.target
this.setState({[name]:value})
}
handleSubmit = event => {
event.preventDefault();
fetch("/api/register", {
method: "POST",
body: JSON.stringify(this.state)
})
.then((result)=> result.json())
.then((info) => { console.log(info); })
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input type="text" name="name" value={this.state.name} placeholder="name" onChange={this.handleChange} />
<input type="text" name="username" value={this.state.username} placeholder="username" onChange={this.handleChange} />
<input type="password" name="password" value={this.state.password} placeholder="password" onChange={this.handleChange} />
<button>Register</button>
</form>
</div>
)
}
}
export default Register
Express code
const express = require("express"),
passport = require("passport"),
User = require("../models/user");
const router = express.Router({mergeParams: true});
// /api before this
router.post("/register", (req, res)=>{
const newUser = new User({
username: req.body.username,
name: req.body.name
});
User.register(newUser, req.body.password, (err, user)=>{
if(err) {
console.log(err);
}
passport.authenticate("local")(req, res, ()=>{
res.redirect("/user/" + user._id);
});
});
});
module.exports = router;
Now im getting a 400 bad request error and another error that says: register:1 Uncaught (in promise) SyntaxError: Unexpected token B in JSON at position 0

I would say that the url from the fetch action is not matching your express route
/api/register > /register
Try adding /api to the express route or remove from the fetch action
I also noticed your route is not returning anything.
You have to return something in the response object.
res.json(newUser);
router.post("/register", (req, res)=>{
const newUser = new User({
username: req.body.username,
name: req.body.name
});
// some code
return res.json(newUser);
});

Related

Getting 404 Error Response in google chrome extension in React js frontend and express backend

I am trying to create a simple form handling experiment where it will put all fetched data from database and display it to user.
I am using 2 separate projects for frontend and backend.
Frontend is in react and backend is in express js.
Here is my express.js code
const express = require("express");
const monggose = require("mongoose");
const bodyParser = require("body-parser");
const { default: mongoose } = require("mongoose");
const cors = require("cors");
const { Router } = require("express");
const app = express();
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
// ================= Connectivity ========
monggose.set("strictQuery", false);
mongoose.connect("mongodb://127.0.0.1:27017/players");
const cricketerSchema = monggose.Schema({
rank: Number,
name: String,
country: String,
dob: Date,
totalRun: Number,
});
const Cricketer = monggose.model("cricketers", cricketerSchema);
// === GET ,POST, DELETE ========
app
.route("/cricketers")
.get(function (request, response) {
Cricketer.find(function (error, foundCricketers) {
if (!error) {
response.send(foundCricketers);
} else {
response.send(error);
}
});
})
.post(function (request, response) {
const c1 = new Cricketer({
// ==== here Rank is the name of the attribute of form field
rank: request.body.Rank,
// ==== here Nank is the name of the attribute of form field
name: request.body.Name,
country: request.body.Country,
dob: request.body.DOB,
totalRun: request.body.TotalRun,
});
c1.save(function (error) {
if (!error) {
console.log("Data inserted successfully");
response.send("Data added successfully...");
} else {
console.log(error);
response.send(error);
}
});
})
.delete(function (request, response) {
Cricketer.deleteMany(function (error) {
if (!error) {
response.send("All Data Deleted");
} else {
response.send(error);
}
});
});
app.listen(3010, function () {
console.log("Server is running at http://localhost:3010");
});
and here is my frontend code.
import { useEffect, useState } from "react";
import axios from "axios";
function App() {
const [name, setName] = useState("zain");
const [rank, setRank] = useState("5");
const [country, setCountry] = useState("india");
const [dob, setDOB] = useState("2023-02-21");
const [totalrun, setRun] = useState("5000");
const [cricketers, setCricketers] = useState([]);
const baseURL = "http://localhost:3010/cricketers";
useEffect(() => {
axios.get(baseURL).then((response) => {
const x = response.data;
setCricketers(x);
});
}, []);
function handlesubmit() {
const collection1 = {
Name: name,
Country: country,
DOB: dob,
TotalRun: totalrun,
Rank: rank,
};
console.log(collection1);
useEffect(() => {
axios
.post(baseURL, collection1)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
});
}
return (
<div>
<label>Cricketer Rank:</label>
<input
type="number"
name="Rank"
value={rank}
onChange={(e) => setRank(e.target.value)}
/>
<br />
<label>Cricketer Name:</label>
<input
type="text"
name="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<br />
<label>Cricketer Country:</label>
<input
type="text"
name="Country"
value={country}
onChange={(e) => setCountry(e.target.value)}
/>
<br />
<label>Cricketer DOB:</label>
<input
type="date"
name="DOB"
value={dob}
onChange={(e) => setDOB(e.target.value)}
/>
<br />
<label>Cricketer TotalRun:</label>
<input
type="number"
name="TotalRun"
value={totalrun}
onChange={(e) => setRun(e.target.value)}
/>
<br />
<button onClick={handlesubmit}>Submit</button>
<ul>
{cricketers.map((i) => (
<li key={i._id}>
<p>
{i.name}
{i.country}
{i.rank}
{i.dob}
{i.totalrun}
</p>
</li>
))}
</ul>
</div>
);
}
export default App;
when page is loaded, it's fetching data from database and showing it into react page component.
For post method getting following error.
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
at Object.throwInvalidHookError (react-dom.development.js:16227:9)
at useEffect (react.development.js:1634:21)
at handlesubmit (App.jsx:29:5)
My need is, I want to use functional component only and I have tried with all different solutions,
like fetch and axios.
It's not working.
When I am calling POST method from POSTMAN api it's working perfectly.
You are calling useEffect inside handleSubmit function. Hooks cannot be called inside a function. They can only be called at top level of a functional component. Refactor the handleSubmit function.
Please remove useEffect in your handleSubmit function. GET request must be put inside useEffect, but POST, PUT, PATCH,... don't. It all has to do with when the request is called. You can read further about useEffect to understand this.

How to use next auth to authenticate through a custom Spring API library and endpoints

I am a newbie to Next.js and moving my front end from React to Next (v4). I've already developed a back end using Spring which connects to a MySQL database hosted on Azure. The API is fully tested and functional on Postman and a React front end. The API includes endpoints allowing for authentication. The API also generates a JWT token.
Moving the front end from React to Next js
In trying to move the front end from React, authentication is the first problem being faced. I chose to try to next_auth, but there seems to be some problems in implementing next_auth using username and password credentials.
Next auth for authenticating with Spring / Java REST APIs
The above leads me to ask if Next auth is even suitable for authenticating with Spring APIs in the first place? Or if a custom method (ie: standard React) would be better? The Next auth documentation seems to prefer using built-in methods like Google, Twitter, etc, with less support for custom credentials methods.
Similar questions on SOF
I didn't find many similar questions on this specific use case. This is the only question I found that talks about Next auth and Spring APIs. There are no answers to the question.
The closest thing to my problem is this question. It says the problem is about the configuration of the JWT token and callback. I followed the directions but it didn't solve the problem.This question is about connecting Next auth to a Spring boot API. This question is generally about how to configure and use Credentials provider.
Based on all of this, I tried the below:
React code (including Postman signature)
The following code in React works fine with the API. I have also extracted the Postman signature in the fetch method.
const AuthForm = () => {
const emailInputRef = useRef();
const passwordInputRef = useRef();
const [isLogin, setIsLogin] = useState(true);
const [isLoading, setIsLoading] = useState(false);
const [isAdmin, setIsAdmin] = useState(false);
const authCtx = useContext(AuthContext);
const switchAuthModeHandler = () => {
setIsLogin((prevState) => !prevState);
};
const submitHandler = (event) => {
event.preventDefault();
const enteredEmail = emailInputRef.current.value;
const enteredPassword = passwordInputRef.current.value;
// optional: Add validation
setIsLoading(true);
if (isLogin) {
// Postman signature here
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("username", enteredEmail);
urlencoded.append("password", enteredPassword);
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
fetch(API_LOGIN_URL, requestOptions)
.then((res) => {
setIsLoading(false);
if (res.ok) {
return res.json();
} else {
return res.json().then((data) => {
let errorMessage = 'Authentication failed!';
throw new Error(errorMessage);
});
}
})
.then((data)=> {
authCtx.login(data.access_token);
const processedData = JSON.stringify(data);
console.log("Admin status "+ processedData);
for(let i = 0; i < processedData.length; i++) {
if(processedData.includes("ROLE_SUPER_ADMIN")) {
console.log("Found Admin");
authCtx.adminAccess(true);
}
if(processedData.includes("ROLE_USER")) {
console.log("Found User");
break;
}
else {
console.log("Not Found");
}
}})
.catch((err) => {
alert(err.message);
});
}
};
return (
<section className={classes.auth}>
<h1>{isLogin ? 'Login' : 'Sign Up'}</h1>
<form onSubmit={submitHandler}>
<div className={classes.control}>
<label htmlFor='email'>Your Email</label>
<input type='email' id='email' required ref={emailInputRef} />
</div>
<div className={classes.control}>
<label htmlFor='password'>Your Password</label>
<input type='password' id='password' required ref={passwordInputRef} />
</div>
<div className={classes.actions}>
{!isLoading && <button>{isLogin ? 'Login' : 'Create Account'}</button>}
{isLoading && <p>Sending request</p>}
<button
type='button'
className={classes.toggle}
onClick={switchAuthModeHandler}
>
{isLogin ? 'Create new account' : 'Login with existing account'}
</button>
</div>
</form>
</section>
);
};
export default AuthForm;
Next.js Application Code
[...nextauth].js
export default NextAuth({
session: {
strategy: "jwt",
secret: process.env.SECRET,
maxAge: 30 * 24 * 60 * 60, // 30 days
},
providers: [
CredentialsProvider({
name: 'credentials',
credentials: {
Username: {label: "Username", type: "text", placeholder: 'app#apptest.com'},
Password: {label: "Password", type: "password"}
},
async authorize(credentials, req) {
// extracted from Postman
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("Username", credentials.Username);
urlencoded.append("Password", credentials.Password);
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,d
redirect: 'follow'
};
const user = fetch(API_LOGIN_URL, {
requestOptions
})
console.log("Credentials are: " + credentials.Username)
if (user) {
// Any object returned will be saved in `user` property of the JWT
return user
} else {
// If you return null or false then the credentials will be rejected
return null
// You can also Reject this callback with an Error or with a URL:
// throw new Error('error message') // Redirect to error page
// throw '/path/to/redirect' // Redirect to a URL
}
},
})],
callbacks: {
async session({ session, token, user }) {
session.user.id = token.id;
session.accessToken = token.accessToken;
return session;
},
async jwt({ token, user, account, profile, isNewUser }) {
if (user) {
token.id = user.id;
}
if (account) {
token.accessToken = account.access_token;
}
return token;
},
}
}
)
Authform.js (login form)
import { useState, useRef, useContext } from 'react';
import classes from './AuthForm.module.css';
import { signIn } from 'next-auth/react';
import { API_LOGIN_URL } from '../Constants';
import { redirect } from 'next/dist/server/api-utils';
function AuthForm () {
const emailInputRef = useRef();
const passwordInputRef = useRef();
async function submitHandler (event) {
event.preventDefault();
const enteredEmail = emailInputRef.current.value;
const enteredPassword = passwordInputRef.current.value;
const result = await signIn('credentials', {
redirect: false,
username: enteredEmail,
password: enteredPassword,
callbackUrl: `${window.location.origin}`
});
console.log("The email " + enteredEmail);
console.log("Result is: " + result.error);
}
return (
<section className={classes.auth}>
<h1>Login</h1>
<form onSubmit={submitHandler}>
<div className={classes.control}>
<label htmlFor='username'>Your Email</label>
<input type='email' id='username' required ref={emailInputRef} />
</div>
<div className={classes.control}>
<label htmlFor='password'>Your Password</label>
<input
type='password'
id='password'
required
ref={passwordInputRef}
/>
</div>
<div className={classes.actions}>
<button>Login</button>
<button
type='button'
className={classes.toggle}
>
</button>
</div>
</form>
</section>
);
}
export default AuthForm;
Errors
On the front end
When actually logging in, I get no errors. If I refresh the browser after restarting the application I get:
[next-auth][warn][NO_SECRET]
https://next-auth.js.org/warnings#no_secret
[next-auth][error][JWT_SESSION_ERROR]
https://next-auth.js.org/errors#jwt_session_error decryption operation
failed { message: 'decryption operation failed', stack:
'JWEDecryptionFailed: decryption operation failed\n' +
The back end
The login actually does reach the back end point (when monitoring the API terminal), but it gives null for the user name and password values.
Main questions
Is Next auth the right framework to authenticate to a Spring API or is it better to write a custom authentication method (or even stick to using React)?
What is wrong with the above code?
Thank you!
In the credentials you have mentioned username but in the form it's email?
Can you update the async authorize(credentials, req) code to the below & try -
const payload = {
email: credentials.email, // make sure this field is mapped correctly
password: credentials.password,
};
const res = await fetch(API_LOGIN_URL, {
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json',
'Accept-Language': 'en-US',
},
});
const user = await res.json();
Also the signIn method's signature seems to be incorrect -
Syntax
signIn('credentials', { redirect: false, password: 'password' })
signIn('email', { redirect: false, email: 'bill#fillmurray.com' })
Usage
const result = await signIn('credentials', {
headers: myHeaders,
body: urlencoded,
redirect: false
});
Please update to
const res = await signIn('credentials', {
redirect: false,
email: values.email,
password: values.password,
callbackUrl: `${window.location.origin}`, // if required
});

FormData not working with Axios Post request - MERN react Js

I've been trying to make a post request to my server(Node Js+Mongodb which runs on localhost too). Axios.post works properly on the client code, however when i try to use formData it doesn't. I can't seem to find any reason why it's not working.
It leaves no error on the console(which makes it more frustrating).
Here is the client code:
someone pls point me to what I might be doing wrong.
import React, { useState } from 'react'
import Axios from 'axios'
export default function InputData() {
const [inputName, setInputName] = useState("")
const [inputAge, setInputAge] = useState(0)
const [inputEmail, setInputEmail] = useState("")
const [userImage, setUserImage] = useState("")
const [info,setInfo] = useState("")
var bodyFormData = new FormData();
bodyFormData.append('name', inputName);
bodyFormData.append('age', inputAge);
bodyFormData.append("email", inputEmail)
const createUser = () => {
Axios.post("http://localhost:3008/createUser",
bodyFormData , { headers: { 'Content-Type': 'multipart/form-data' } }).then(function (response) {
//handle success
console.log(response);
}).catch(function (response) {
//handle error
console.log(response);
});
}
return (
<div>
<form onSubmit={createUser} encType="multipart/form-data">
<div>
<input type="text" placeholder='enter name' value={inputName} width={400} onChange={(e) => setInputName(e.target.value)} /><br/>
<input type="number" placeholder='enter age' width={400} value={inputAge} onChange={(e) => setInputAge(e.target.value)} /><br/>
<input type="email" placeholder='enter e-mail' width={400} value={inputEmail} onChange={(e) => setInputEmail(e.target.value)} /><br />
<button>Submit</button>
</div>
</form>
</div>
)
}
axios: "^0.27.2",
react: "^18.2.0"
Couple of points:
You're probably not seeing any errors (output) in the console because you're submitting the form. You can change your onSubmit handler to include preventDefault:
const createUser = (e) => {
Axios.post("http://localhost:3000/createUser", bodyFormData, { headers: { 'Content-Type': 'multipart/form-data' } })
.then(console.log)
.catch(console.error);
e.preventDefault();
}
You can also keep it as is and see the previous output by persisting the logs of your browse across requests, in Firefox this checkbox:
You should add method=post to your form
I think you will receive all the data from the event [createUser method] on submitting the form, Try removing the header If you still have problem try as below, If you still have the problem check the server side Post method Params
let data = { name: inputName, age: inputAge, email: inputEmail }
Axios.post("http://localhost:3008/createUser",data )
.then(function (response) { console.log(response); })
.catch(function (response) { console.log(response); });

Firebase, React: How do I display http errors on client side?

I'm building a project with React and Firebase. I've split it into two repos - a backend repo for firebase functions, and a client-side repo for React. Part of my project involves user registration, and I want to be able to send any errors (eg, email already in use, weak password) to the client side, but I'm not sure how. Does anyone have suggestions about how I can pass backend errors to the client?
I know that I could move the firebase API call to client side which would make error handling much easier, but this would create complications.
Code as follows:
Registration component VenueRegister
import React from 'react'
import Header from './Header'
import TextField from '#material-ui/core/TextField';
import Button from '#material-ui/core/Button'
import axios from 'axios'
import { auth } from 'firebase/app'
class VenueRegister extends React.Component {
constructor() {
super();
this.state = {
email: '',
password:'',
confirmPassword:'',
venueName:'',
venueAddress:''
};
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
handleChange(e){
this.setState({
[e.target.name]: e.target.value
})
}
handleSubmit(e) {
console.log("submit function reached");
e.preventDefault();
const venueData = {
email: this.state.email,
password: this.state.password,
confirmPassword: this.state.confirmPassword,
venueName: this.state.venueName,
venueAddress: this.state.venueAddress
};
axios("http://localhost:5000/gig-fort/us-central1/api/registerVenue", {
method: "POST",
headers: {
"content-type": "application/json",
},
data: venueData,
})
.then((res) => {
console.log(res.data);
})
.catch((err) => {
console.error(err);
});
}
render() {
return (
<>
<Header />
<h1 className="heading-venue-reg">Register your venue</h1>
<form onSubmit = {this.handleSubmit}>
<TextField
required
id="standard-required"
name = 'email'
label="Required"
defaultValue="email"
placeholder="email"
onChange = {this.handleChange}
/>
<TextField
required
id="standard-required"
name = 'password'
label="Required"
defaultValue="password"
placeholder="password"
onChange = {this.handleChange}
/>
<TextField
required
id="standard-required"
name = 'confirmPassword'
label="Required"
defaultValue="confirm password"
placeholder="confirm password"
onChange = {this.handleChange}
/>
<TextField
required
id="standard-required"
name = 'venueName'
label="Required"
defaultValue="venue name"
placeholder="venue name"
onChange = {this.handleChange}
/>
<TextField
required
id="standard-required"
name = 'venueAddress'
label="Required"
defaultValue="venue address"
placeholder="venue address"
onChange = {this.handleChange}
/>
<Button type="submit">Submit</Button>
</form>
</>
);
}
}
export default VenueRegister
Backend function for venue registration:
app.post('/registerVenue',(req,res) =>{
const newVenue = {
email: req.body.email,
password: req.body.password,
confirmPassword: req.body.confirmPassword,
venueName: req.body.venueName,
venueAddress: req.body.venueAddress
}
let errors = {}
if(isEmpty(newVenue.email)){
errors.email = 'Email must not be empty'
}else if (!isEmail(newVenue.email)){
errors.email = 'must be a valid email address'
}
if(Object.keys(errors).length >0){
return res.status(400).json(errors)
}
let token, userId
db.doc(`/user/${newVenue.venueName}`).get()
.then(doc => {
if(doc.exists){
return res.status(400).json({venueName: `This venue name is already taken`})
} else {
return firebase
.auth()
.createUserWithEmailAndPassword(newVenue.email, newVenue.password)
}
})
.then(data=> {
userId = data.user.uid;
return data.user.getIdToken()
})
.then(idToken => {
token = idToken
const venueDetails ={
email: newVenue.email,
venueName: newVenue.venueName,
venueAddress: newVenue.venueAddress,
createdAt: new Date().toISOString(),
userId
}
return db.doc(`/users/${newVenue.venueName}`).set(venueDetails)
})
.then(() => {
return res.status(201).json({token})
})
.catch(err => {
console.error(err)
if(err.code === 'auth/email-already-in-use'){
return res.status(400).json({email: 'Email is already in use'})
} else {
return res.status(500).json({error:err.code})
}
//TODO: put in conditional statement that sends 'weak password error' to client
})
})
In the frontend, when receiving the data from the backend, you should check your response data for errors. It is very likely you would want a util function for that since it is a common task across almost all requests (hence re-utilize).
So you would like to check the response.status and then set a new state like a hasError or something that will cause a re-render to your component and show, i.e, a child component that displays the error to the user and gives the ability to retry the operation.

Axios data coming up as ImmutableMultiDict([]) when sent to Flask POST route, but work with Postman

I am using Flask to create a POST method to register a new user in my MySQL database. I tried created an Axios method to send the POST request from my React JS application. I was testing with Postman, and I am sending it using application/x-www-form-urlencoded. The registration works in Postman, but the data comes up as ImmutableMultiDict([]).
Flask code:
#app.route('/registerUser', methods=['POST'])
def registerUser():
data = request.form
if len(data) is 0:
return 'Request was empty!'
username = data['username']
password = data['password']
email = data['email']
user = User(username=username,
password=password,
email=email)
db.session.add(user)
db.session.commit()
return 'Registration success!'
return 'Registration failed!'
React code:
class Signup extends Component {
constructor(props){
super(props);
this.state = {
username: '',
password: '',
email: ''
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.clearInputs = this.clearInputs.bind(this);
}
handleChange(event){
event.preventDefault();
this.setState({[event.target.name]: event.target.value});
}
handleSubmit(event){
event.preventDefault();
const config = {
headers: { 'content-type': 'application/x-www-form-urlencoded' }
}
axios.post(`http://localhost:5000/registerUser`,
this.state, config)
.then(res => {
alert(res.data);
})
.catch((err) => {
alert(err);
});
}
render(){
return (
<div className='signup'>
<form onSubmit={this.handleSubmit}>
<label>
Username
<input type='text' name='username'
value={this.state.username}
onChange={this.handleChange}/><br/>
</label>
<label>
Password
<input type='password' name='password'
value={this.state.password}
onChange={this.handleChange}/><br/>
</label>
<label>
Email
<input type='text' name='email'
value={this.state.email}
onChange={this.handleChange}/><br/>
</label>
<input type='submit' value='Submit' /><br/>
</form>
</div>
);
}
}
export default Signup;
Why is the data not properly sending from Axios? I am using CORS in flask, and both Postman and Axios should be sending the same form data.
EDIT: I changed the POST request to use request.form
However, Postman works, but Axios still doesn't.
From Postman:
ImmutableMultiDict([('username', 'person'), ('password', 'Password1'), ('email', 'example#example.com')])
From Axios: ImmutableMultiDict([('{"username":"someone","password":"Password1","email":"email#example.com"}', '')])
Is Axios misconfigured?
I figured out the problem. By default, Axios sends data by JSON format. In order to comply with urlencoded, you would need to build a new URLSearchParams object to send instead. See the documentation
This is the working React code:
handleSubmit(event){
event.preventDefault();
const config = {
headers: { 'content-type': 'application/x-www-form-urlencoded' }
}
const getParams = (obj) => {
const params = new URLSearchParams();
const keys = Object.keys(obj);
for(let k of keys){
params.append(k, obj[k]);
}
return params;
}
axios.post(`http://localhost:5000/registerUser`,
getParams(this.state), config)
.then(res => {
alert(res.data);
this.clearInputs();
})
.catch((err) => {
alert(err);
});
}
This works with my OP Flask code.
I think you will have to coerce the request data into type JSON within your registerUser route since you're trying to access a JSON response but you sent the request over in application/x-www-form-urlencoded format. application/x-www-form-urlencoded is the default form content type specification created by the W3C and is usually used to send text/ASCII data. Maybe you could try the following and see if you get the expected JSON response:
app.route('/registerUser', methods=['POST'])
def registerUser():
requestJson = request.get_json(force=True)
# check that requestJson is correct if so
# create and save your new user to your db
return 'Registration failed!'
If your requestJson is as expected then you can just pull out the required fields and save your new user to your database. If not please print out the request you're receiving to see how it can be appropriately parsed.
Hopefully that helps!

Resources