I am creating a Login form in JavaScript and am trying to send this form to my Ruby on Rails backend.
I have two problems:
-
When the form loads, it triggers the eventListener and sends the blank form’s data to the backend. I have e.preventDefault() commented out in the second function below because I kept getting the error that it is not a function. Note: in the backend for Rails, I get the following message when I type in params. "Permitted: false" concerns me.
<ActionController::Parameters {"controller"=>"sessions", "action"=>"create", "session"=>{}} permitted: false>
-
When I fill in the form with an email and password and click the submit button, the loginData (from
loginButton.addEventListener("submit", submitLogin(loginData)
submits a blank value for the email and ‘password’ for the password (which are the default values I set to test the values) even though these elements are filled in in the form with an actual email address and password.
Function loading login form (note: this loads just fine):
// create the elements
var div = document.createElement("div"),
log = document.createElement("div"),
loginForm = document.createElement("form"),
//set form attributes
loginForm.setAttribute("method", "POST");
// set body styles
document.body.style.textTransform = "capitalize";
log.id = "login";
log.innerHTML = "login";
// set loginForm styles
loginForm.id = "loginForm";
// set the elements and styles on the form
loginForm.innerHTML =
"<label>username</label><br/>" +
"<input type='text' id='login-email' value='' placeholder='email' style='" +
inputStyles +
"' /><br/>" +
"<label>password</label><br/>" +
"<input type='password' id='login-password' value='value' placeholder='*************' style='" +
inputStyles +
"' /><br/>" +
"<input type='submit' id='login-button' value='Login' style='" +
btnStyles +
"' />" +
"<p><a style='" +
forgetStyles +
"' href='#'>forget password ?</a></p><br/>";
// append the buttons and form on main-div
div.appendChild(log);
div.appendChild(loginForm);
// append main-div on the body
document.body.appendChild(div);
//get login form values to submit
let loginEmail = document.getElementById("login-email").value;
let loginPassword = document.getElementById("login-password").value;
let loginData = { member: { loginEmail, loginPassword } };
}
SubmitLogin Function (fetch request to Rails backend):
async function submitLogin(e) {
// e.preventDefault();
const loginData = new FormData(e.target);
debugger;
let options = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin":
"file:///Users/awb/Coding/Flatiron/Projects/bookclub-javascript-rails-api/bookclub-frontend-javascript/index.html",
"Access-Control-Allow-Methods": "POST",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
Accept: "application/json",
},
body: JSON.stringify(loginData),
};
fetch("http://localhost:3000/login", options)
.then((resp) => {
resp.json();
})
.then((member) => {
console.log(member);
return new Member(member);
});
}
If it matters, this is the order of my scripts at the bottom of my index.html page:
<script src="src/suggestion.js"></script>
<script src="src/member.js"></script>
<script src="src/gathering.js"></script>
<script src="src/book_group.js"></script>
<script src="src/book.js"></script>
<script src="src/login_registration_form.js"></script>
<script src="src/index.js"></script>
Where index.js calls the function "loadRegistrationLogin()" as the last line on index.js
My routes are:
Rails.application.routes.draw do
resources :members, only [:create, :index, :show]
resources :registrations, only: [:create]
resources :sessions, only: [:create]
post '/login', to: 'sessions#create'
delete '/logout', to: 'sessions#destroy'
get '/logged_in', to: 'sessions#is_logged_in?'
root to: "static#home"
end
and finally, my session controller:
class SessionsController < ApplicationController
include CurrentMemberConcern
skip_before_action :verify_authenticity_token
def create
member = Member
.find_by(email: params[:member][:email])
.try(:authenticate, params[:member][:password])
if member
login!
render json: {
status: :created,
logged_in: true,
member: member
}
else
render json: {
status: 401,
errors: ['No such member', 'Verify credentials and try again or sign up']
}
end
end
end
Your form is submitting automatically because of the way you’ve set the event handler. The
.addEventListener()
API requires a reference to a callback function as the second argument. But you passed a function call with arguments like this:loginButton.addEventListener("submit", submitLogin(loginData));
You have two choices to fix this:
loginData
to be available to the handler in some other fashion.loginButton.addEventListener("submit", submitLogin);
loginButton.addEventListener("submit", ()=>submitLogin(loginData));
Option 2 is generally preferred when needing to pass parameters to the handler. But you’ll see below, for you, option one is the way to go.
The leads to the next problem –
submitLogin()
function itself.In your eventListener setup you went out of your way to pass a parameter to this function – yet it isn’t used. You correctly attempt to create a new
FormData()
Object. But interestingly enough you passe.target
, which is thebutton
element. That won’t work Reference.To fix that change:
const loginData = new FormData(e.target);
to: (assuming only one form on the page)
const loginData = new FormData(document.forms[0]);
But we aren’t done yet. Using
e.preventDefault()
is unnecessary if you set up your button correctly. A button withtype="submit"
is designed to submit the form to the server. That’s also true for a button with notype
attribute at all. You clearly don’t want to submit the form, so don’t put a submit button on it.Change the login button from:
type="submit"
To:
type="button"
Now you can remove the
e
parameter from your function.All of that should get you a lot closer to success.
purchasing tadalafil online – site generic tadalafil reviews