Reputation: 752
I'm trying to make a simple form that allows users to sign up for a new account using React JS and Ruby on Rails API. I am using the devise/devise authentication API gem for my account. I made a form with react, but when I submit my form it returns a 404 not found error.
Interesting thing is that when I use postman to run the exact same request, it registers a new user successfully.
I've tried connecting it to other routes, changing the request type but nothing seems to work. I'm running my React app on port 8080 and rails 3000.
Here is my current code:
import React, { Component } from "react";
import axios from "axios";
class Registration extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
password_confirmation: "",
registrationErrors: ""
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
handleSubmit(event) {
event.preventDefault();
console.log("form submitted");
const { email, password, password_confirmation } = this.state;
axios
.post(
"/auth",
{
user: {
email,
password,
password_confirmation
}
},
{ withCredentials: true }
)
.then(response => {
console.log("registration res", response);
})
.catch(error => {
console.log("egistration", error);
});
// axios returns a promise so need to use a then to convert it to json
// then give out errors if there are any
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input
type='email'
name='email'
placeholder='Email'
value={this.state.email}
onChange={this.handleChange}
required
/>
<input
type='password'
name='password'
placeholder='Password'
value={this.state.password}
onChange={this.handleChange}
required
/>
<input
type='password'
name='password_confirmation'
placeholder='Password Confirmation'
value={this.state.password_confirmation}
onChange={this.handleChange}
required
/>
<button type='submit'>Register</button>
</form>
</div>
);
}
}
export default Registration;
app/controllers/auth/registrations_controller.rb
module Auth
class RegistrationsController < DeviseTokenAuth::RegistrationsController
def new
user = User.new
end
def create
user = User.new(sign_up_params)
if user.save
render json: {status: "SUCCESS", message: "added a new user!", data: user}, status: :ok
else
render json: {status: "ERROR", message: "couldn't add a user", data: user.errors}, status: :unprocessable_entity
end
end
private
def sign_up_params
params.permit(:name, :email, :password, :password_confirmation)
end
def account_update_params
params.permit(:name, :email)
end
end
end
Rails routes
Rails.application.routes.draw do
mount_devise_token_auth_for 'User', at: 'auth', controllers: {
registrations: 'auth/registrations'
}
end
new_user_session GET /auth/sign_in(.:format) devise_token_auth/sessions#new
user_session POST /auth/sign_in(.:format) devise_token_auth/sessions#create
destroy_user_session DELETE /auth/sign_out(.:format) devise_token_auth/sessions#destroy
new_user_password GET /auth/password/new(.:format) devise_token_auth/passwords#new
edit_user_password GET /auth/password/edit(.:format) devise_token_auth/passwords#edit
user_password PATCH /auth/password(.:format) devise_token_auth/passwords#update
PUT /auth/password(.:format) devise_token_auth/passwords#update
POST /auth/password(.:format) devise_token_auth/passwords#create
cancel_user_registration GET /auth/cancel(.:format) auth/registrations#cancel
new_user_registration GET /auth/sign_up(.:format) auth/registrations#new
edit_user_registration GET /auth/edit(.:format) auth/registrations#edit
user_registration PATCH /auth(.:format) auth/registrations#update
PUT /auth(.:format) auth/registrations#update
DELETE /auth(.:format) auth/registrations#destroy
POST /auth(.:format) auth/registrations#create
auth_validate_token GET /auth/validate_token(.:format) devise_token_auth/token_validations#validate_token
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
I would appreciate any insights.
UPDATE: I tried changing the port number of my react app to 3000 and my rails API to 3001 since the url was inputted in postman was a localhost 3000. But still the same error is returned.
UPDATE2: Below are the network tabs.
UPDATE: Attached is the postman headers and payload
Upvotes: 2
Views: 1017
Reputation: 1585
I believe the problem is in the axios body. You're sending the fields inside an user json key, and not specifying the keys for the other fields. Try removing that key and just sending the e-mail, password and password confirmation.
Like this:
axios.post("/auth", {
email: email,
password: password,
password_confirmation: password_confirmation
},
{ withCredentials: true }
)
If that doesn't work, it might have something to do with the withCredentials option.
In any case, take a look into axios' docs to see it's options https://github.com/axios/axios
You could use the Network tab to analyse the request sent and see how the params and headers differ from the ones on postman.
Upvotes: 0