Fetch API POST, not sending <form> data - javascript

I keep getting a 500 error server when I try to submit form data to my API /users/signup. I verified that the API works using Postman so I think the way I am doing my fetch post is wrong. What is the best practice here?
JS
document.getElementById("create_user").addEventListener("click", (e) => {
e.preventDefault();
const signup = {
username: document.querySelector("#create_username").value.toString(),
email: document.querySelector("#create_email").value.toString(),
password: document.querySelector("#create_password").value.toString()
}
const data = new FormData();
data.append("json", JSON.stringify(signup));
fetch('/users/signup', {
method: 'POST',
body: data
})
.then((response) => response.json())
.catch((error) => {
console.error('Error:', error);
});
});
HTML
<form class="hide" id="sign_up_form">
<div class="form-row">
<h3>Sign up</h3>
</div>
<div class="form-row">
<div class="form-group col">
<label for="create_username">Username</label>
<input id="create_username" name="username" type="text" class="form-control" placeholder="Username">
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="create_email">Email</label>
<input id="create_email" name="email" type="email" class="form-control" placeholder="Email">
</div>
</div>
<div class="form-row">
<div class="form-group col">
<label for="create_password">Password</label>
<input id="create_password" name="password" type="password" class="form-control" placeholder="Password">
<small id="passwordHelp" class="text-muted">
Must be at least 8 characters long
</small>
</div>
</div>
<div class="form-row flex-end">
<div class="form-group col-auto">
<button id="create_user" type="submit" class="btn btn-warning mb-2">Sign up</button>
</div>
</div>
<div class="form-row">
<span class="mr-2">Already have an account?</span>Login
</div>
</form>

You don't need to create a form object, you can directly send the json data to your backend.
Add yous json data in the body and the 'Content-Type': 'application/json' header in the request.
The value property of the querySelector method will always return string, you don't need to call toString method on it.
Try this.
document.getElementById("create_user").addEventListener("click", (e) => {
e.preventDefault();
const signup = {
username: document.querySelector("#create_username").value,
email: document.querySelector("#create_email").value,
password: document.querySelector("#create_password").value
}
fetch('/users/signup', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(signup)
})
.then((response) => response.json())
.then(data => console.log(data))
.catch((error) => {
console.error('Error:', error);
});
});

Related

Trying to read multipart/form-data in Django

I am learning NextJS/Django. I am trying to send some FormData to my Django back end. It contains some strings and an image file. But, I am getting the following error:
django.http.multipartparser.MultiPartParserError: Invalid boundary in multipart: None
Form:
<form
className={styles.formContainer}
method="post"
encType="multipart/form-data"
onSubmit={handleSubmit}
>
<div className="form-group">
<label htmlFor="email" className={styles.text}>
Email address
</label>
<input
type="email"
className="form-control"
id="email"
aria-describedby="emailHelp"
placeholder="Change email here"
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="form-group">
<label htmlFor="image" className={styles.text}>
Image
</label>
<input
type="file"
className="form-control"
id="image"
accept="image/*"
onChange={(e) => setImageLink(e.target.files[0])}
/>
</div>
<div className="form-group">
<label htmlFor="description" className={styles.text}>
Description
</label>
<textarea
className="form-control"
id="description"
rows="5"
onChange={(e) => setDescription(e.target.value)}
></textarea>
</div>
<button
type="submit"
className="btn btn-primary"
style={{ marginTop: "7px" }}
>
Submit
</button>
</form>
Submit Button:
function handleSubmit(e) {
e.preventDefault();
let data = new FormData();
data.append("userID", loggedInID);
data.append("email", email);
data.append("description", description);
data.append("image", imageLink);
fetch("http://127.0.0.1:8000/user/edit_profile/", {
method: "POST",
headers: {
"Content-Type": "multipart/form-data",
"X-CSRFToken": csrfToken,
},
credentials: "include",
body: data,
}).then((response) => response);
}
Django View:
#parser_classes([FormParser, MultiPartParser])
#csrf_exempt
def editProfileView(request):
print(request.data)
return JsonResponse({})
The Django view is currently unfinished, as I cannot read the data in the sent FormData. Any help is appreciated.

jquery formdata returns null in express req.files

I am using Bootstrap/jquery for client side. On server side I am using node.js and express
The form is as follows:
<form id="signupform" action="">
<h2>Sign Up</h2>
<p>Please fill in this form to create an account!</p>
<hr>
<div class="form-group">
<input type="text" class="form-control" id="username" placeholder="Username" required="required">
</div>
<div class="form-group">
<input type="email" class="form-control" id="email" placeholder="Email" required="required">
</div>
<div class="form-group">
<input type="number" class="form-control" id="contact" placeholder="Contact" required="required">
</div>
<div class="form-group">
<input type="password" class="form-control" id="password" placeholder="Password" required="required">
</div>
<div class="custom-file">
<label class="custom-file-label" for="cover">Profile Picture</label>
<input type="file" class="custom-file-input" id="cover">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-lg" id="sign-up">Sign Up</button>
</div>
</form>
My jquery is as follows:
$(document).ready(function(){
$("#sign-up").click(function(event){
event.preventDefault();
var formData = new FormData();
formData.append("username",$("#username").val())
formData.append("email",$("#email").val())
formData.append("contact",$("#contact").val())
formData.append("password",$("#password").val())
formData.append("cover",$("#cover")[0].files)
$.ajax({
url: "http://localhost:3000/users/",
type: 'POST',
data: formData,
success: function (data) {
alert(data)
},
cache: false,
contentType: false,
processData: false
});
});
});
On server side, when I view the incoming request I see this:
body: {
username: 'Sree',
email: 'example#gmail.com',
contact: '1',
password: '1',
cover: '[object FileList]'
},
On the server side I am using express-fileupload, but the image is being sent in the body instead of req.files. How to send formData's file to req.files instead of body?
You should be passing a File object to append(), to access the file object use the prop method to get access to the FileList and take the item at the first index
formData.append("cover", $("#cover").prop('files')[0])

Display error message in Modal using Ajax, laravel

I'm new to Laravel, I have a problem displaying errors on my project. I'm using laravel request for validation and AJAX to submit form inside a modal.
I would like to see the error message for each field that are inputted incorrectly. However, I'm getting this error:
The Given data is invalid
I checked the network tab, and I'm seeing the errors there but I can't figure out why this is not showing in my fields.
Here's the error:
Here's my Ajax
//add user code here
$(document).on("click", "#addUserBtn", function (e) {
e.preventDefault();
const first_name = $("#addModal [name=first_name]").val();
const middle_name = $("#addModal [name=middle_name]").val();
const last_name = $("#addModal [name=last_name]").val();
const email = $("#addModal [name=email]").val();
const cellphone = $("#addModal [name=cellphone]").val();
const userType = $("#addModal [name=user_type]").val();
const payload = {
first_name: first_name,
middle_name: middle_name,
last_name: last_name,
email,
cellphone,
user_type: userType
}
$("#addModal .fa-spinner").removeClass('d-none');
$.ajax({
url: "/users-listing",
data: payload,
type: "POST",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
}).done(function(res) {
$("#addModal .fa-spinner").addClass('d-none');
$("#addModal .form-message-container").html(res.message).addClass('text-success').fadeIn(1000);
table.draw(false);
setTimeout(() => {
$("#addModal .form-message-container").html('').removeClass('text-success').fadeOut();
$("#addModal [name=first_name]").val('');
$("#addModal [name=middle_name]").val('');
$("#addModal [name=last_name]").val('');
$("#addModal [name=email]").val('');
$("#addModal [name=cellphone]").val('');
$("#addModal #closeModal").click();
}, 3000);
}).fail(function(err) {
$("#addModal .fa-spinner").addClass('d-none');
$("#addModal .form-message-container").html(err.responseJSON.message).addClass('text-danger').fadeIn(5000);
setTimeout(() => {
$("#addModal .form-message-container").html('').removeClass('text-danger').fadeOut();
}, 5000);
});
});
// code end here
Here's my controller "Store"
public function store(UserRequest $request)
{
$data = $request->all();
$data['password'] = Hash::make(Str::random(10));
$data['status'] = 1;
$user = User::create($data);
$user->sendPasswordResetNotification(Str::random(60));
return response()->json(['code' => 200, 'message' => 'User added succesfully'], 200);
exit;
}
Request code
public function rules()
{
return [
'id' => 'bail|nullable',
'first_name' => 'required|string|min:2',
'middle_name' => 'string|nullable',
'last_name' => 'required|string|min:2',
'user_type' => 'required',
'cellphone' => ['nullable','max:15', Rule::unique('users', 'cellphone')->whereNull('deleted_at')->ignore($this->id, 'id')],
'email' => ['required', 'email', Rule::unique('users', 'email')->whereNull('deleted_at')->ignore($this->id, 'id')],
'status' => 'numeric'
];
}
My blade code
<div class="modal-body m-2">
<form id="adduserForm">
{{ csrf_field() }}
<div class="row form-group">
<div class="col">
<label>First name</label>
<input name="first_name" id="first_name" type="text" class="form-control" placeholder="" autocomplete="off">
</div>
<div class="col">
<label>Middle name</label>
<input name="middle_name" type="text" id="middle_name" class="form-control" placeholder="" autocomplete="off">
</div>
</div>
<div class="row form-group">
<div class="col">
<label>Last name</label>
<input name="last_name" type="text" id="last_name" class="form-control" placeholder="" autocomplete="off">
</div>
<div class="col">
<label>Email</label>
<input name="email" type="email" id="email" class="form-control" placeholder="" autocomplete="off">
</div>
</div>
<div class="row form-group">
<div class="col">
<label>Cellphone</label>
<input name="cellphone" type="number" id="cellphone" class="form-control" placeholder="" autocomplete="off">
</div>
</div>
<div class="row form-group">
<div class="col">
<label>User Type</label>
<select name="user_type" class="form-control form2 selectpicker" data-style="btn btn-secondary">
<option value="0">Property Owner</option>
<option value="1">Admin</option>
<option value="2">Treasury</option>
<option value="3">Assessor</option>
</select>
</div>
</div>
<div class="row form-group text-right mt-3">
<div class="col">
<div class="form-message-container text-left">
<span class="form-message"></span>
</div>
</div>
<div class="col">
<button id="closeModal" type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button id="addUserBtn" type="button" class="btn btn-primary right">
<span class="fa fa-spin fa-spinner mr-1 d-none"></span> Save Changes</button>
</div>
</div>
</form>
</div>
Add in your blade to every field:
<!-- ... -->
<div class="col">
<label>First name</label>
<div class="validation-message"></div>
<input name="first_name" id="first_name" type="text" class="form-control" placeholder="" autocomplete="off">
</div>
<!-- ... -->
And to your js:
// ...
$.ajax({
url: "/users-listing",
data: payload,
type: "POST",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
}).done(function(res) {
$("#addModal .fa-spinner").addClass('d-none');
$("#addModal .form-message-container").html(res.message).addClass('text-success').fadeIn(1000);
table.draw(false);
setTimeout(() => {
$("#addModal .form-message-container").html('').removeClass('text-success').fadeOut();
$("#addModal [name=first_name]").val('');
$("#addModal [name=middle_name]").val('');
$("#addModal [name=last_name]").val('');
$("#addModal [name=email]").val('');
$("#addModal [name=cellphone]").val('');
$("#addModal #closeModal").click();
}, 3000);
}).fail(function(err) {
$("#addModal .fa-spinner").addClass('d-none');
$("#addModal .form-message-container").html(err.responseJSON.message).addClass('text-danger').fadeIn(5000);
setTimeout(() => {
$("#addModal .form-message-container").html('').removeClass('text-danger').fadeOut();
}, 5000);
for (var [ el, message ] of Object.entries(err.responseJSON.errors)) {
$('#' + el).addClass('is-invalid');
$('#' + el).prev('.validation-message').text(message).addClass('is-invalid');
}
});
// ...
I was able to solve this by changing my route, and the error handling in AJAX.
Thanks for all the inputs ideas here. :)
My fix:
AJAX error code

Unable to post record using vue and laravel backend

When i try to submit a record to my SQL from vue component with laravel API nothing happens. I have compared my code to other working code but nothing seem to work.
Here is my register method:
register() {
axios
.post('/api/register', this.user)
.then(res => {
console.log(user)
})
.catch(err => {
console.log(err.message)
})
},
Here is the register form:
<template>
<form>
<div class="form-group">
<input
type="text"
v-model="user.name"
name="username"
class="form-control"
id="name"
placeholder="Email or username"
/>
<div class="validation"></div>
</div>
<div class="form-group">
<input
v-model="user.email"
type="email"
class="form-control"
name="email"
id="password"
placeholder="Your Email"
/>
<div class="validation"></div>
</div>
<div class="form-group">
<input
v-model="user.password"
type="password"
class="form-control"
name="password"
placeholder="Your Password"
data-rule="password"
/>
<div class="validation"></div>
</div>
<div id="errormessage"></div>
<div class="text-center">
<button type="submit" title="Register" v-on:click="register">Login</button>
</div>
</form>
</template>
My laravel page:
<section id="pricing" class="wow fadeInUp section-bg">
<div class="container">
<header class="section-header">
<h3>Register</h3>
<p>Come prepared!!</p>
</header>
<div class="row flex-items-xs-middle flex-items-xs-center">
<div class="col-xs-12 col-lg-6">
<div class="card">
<div class="card-header">
<div id="app">
<register></register>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
Here is my controller:
if ($v->fails())
{
return response()->json([
'status' => 'error',
'errors' => $v->errors()
], 422);
}
$user = new User;
$user->name = $request->name;
$user->email = $request->email;
$user->password = Hash::make($request->password);
$user->save();
return response()->json(['status' => 'success'], 200);
}
The record should post successfully, however nothing happens. I only see the parameters on my url like so, and I don't get any error on console.
You'll need to prevent the default form submission behavior first, then trigger your own register method.
<form #submit.prevent="register">

Angular log in doesn't work iphone 6

i have a problem with log in in my site - it doesn't work on iphone 6.
Here's my code:
JS:
$scope.signin = function() {
$http({
method: 'POST',
url: link,
data: $.param({
action: 'sign_in',
username: $scope.username,
password: $scope.password
}),
withCredentials: true,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function successCallback(response){
if (response.data === true)
console.log(response);
$location.path('/home');
} else {
console.log('wrong stuff');
}
}, function errorCallback(response){
console.log(response);
console.log('error');
});
}
HTML:
<div class="container" ng-controller="Ctrl">
<form class="form-signin">
<h2 class="form-signin-heading">Please sign in</h2>
<label for="username" class="sr-only">Email address</label>
<input type="username" ng-model="username" id="username" class="form-control" placeholder="Username" required>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" ng-model="password" id="inputPassword" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" ng-click="signin()">Sign in</button>
</form>
</div>
In my website on computer after click "Sign in" i get cookies from server, and angular rout move me to "/home".
When i click "Sign in" on iphone 6 it looks like it is failing when the response returned by the server, and nothing happens.
Thanks for answers in advance.

Categories