Hello!
I am trying to save POST data to the database using JavaScript Fetch API but encounter issues with saving the data to my model instance.
Could someone please take a look at my codes and guide/explain what I am doing wrong?
The POST data is sent to the view and I can see a dictionary in the console containing the POST data. However, the POST data is not saved. In the browser console, I can see that the fields are empty, and therefore rejected by the database.
Currently I am trying to validate the form at the database level, not client side.
Appreciate all help!
View:
@login_required(redirect_field_name="authapp:signin")
def customerinfo(request, user_id, first_name):
if request.headers.get("X-Requested-With") == "XMLHttpRequest":
try:
post_data = json.loads(request.body)
print(post_data)
except json.JSONDecodeError:
return JsonResponse({"error": "Invalid JSON data"}, status=400)
if request.method == "POST":
form_data = CustomerInfoUpdateForm(post_data)
if form_data.is_valid():
print("Form is valid")
user = request.user
user.first_name = post_data["firstName"]
user.last_name = post_data["lastName"]
user.mobile_number = post_data["phoneNumber"]
user.email = post_data["emailAddress"]
user.save()
else:
form_data = CustomerInfoUpdateForm()
return JsonResponse({"form_data": form_data}, safe=True)
context = {}
return render(request, "jewstore_main_app/customerinfo.html", context)
Template code:
<div class="d-flex flex-column">
<form action="#" method = "POST" id="customerInfoForm">
{% csrf_token %}
<fieldset>
<div class="kaycee-MyAccount-content">
<div class="kaycee-notices-wrapper"></div>
<div class="p-3 d-flex flex-column">
<p class="kaycee-form-row kaycee-form-row--wide form-row form-row-wide">
<label for="first_name">Förnamn <span
class="required">*</span></label>
<input type="text" class="kaycee-Input kaycee-Input--text input-text"
name="first_name" id="account_first_name" autocomplete="given-name"
value="">
</p>
<p class="kaycee-form-row kaycee-form-row--wide form-row form-row-widet">
<label for="last_name">Efternamn <span
class="required">*</span></label>
<input type="text" class="kaycee-Input kaycee-Input--text input-text"
name="last_name" id="account_last_name" autocomplete="family-name"
value="">
</p>
<div class="clear"></div>
<p class="kaycee-form-row kaycee-form-row--wide form-row form-row-wide">
<label for="phone">Telefonnummer <span
class="required">*</span></label>
<input type="tel" class="kaycee-Input kaycee-Input--email input-text"
name="phone" id="account_phone" autocomplete="email"
value="">
</p>
<p class="kaycee-form-row kaycee-form-row--wide form-row form-row-wide">
<label for="email">Mail <span
class="required">*</span></label>
<input type="email" class="kaycee-Input kaycee-Input--email input-text"
name="email" id="account_email" autocomplete="email"
value="">
</p>
</div>
<div class="clear"></div>
<p>
<button type="submit" class="kaycee-Button button" name="save_account_details"
value="" id="customerInfoUpdateButton">Uppdatera
</button>
</p>
</fieldset>
</form>
</div>
JavaScript code:
document.addEventListener("DOMContentLoaded", () => {
const customerInfoForm = document.getElementById("customerInfoForm");
// EVENTLISTENERS
customerInfoForm.addEventListener('submit', validateCustomerInfo);
// FUNCTIONS
// Form submit function
function getToken(name) {
let cookieValue = null;
if (document.cookie && document.cookie != '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getToken('csrftoken')
function validateCustomerInfo(e) {
e.preventDefault();
// Constants related to customer info page
let firstName = document.getElementById("account_first_name").value;
let lastName = document.getElementById("account_last_name").value;
let phoneNumber = document.getElementById("account_phone").value;
let emailAddress = document.getElementById("account_email").value;
fetch("", {
method: 'POST',
headers: {
"Accept": "application/json",
"X-Requested-With": "XMLHttpRequest",
"X-CSRFToken": csrftoken
},
body: JSON.stringify({ "firstName": firstName, "lastName": lastName, "phoneNumber": phoneNumber, "emailAddress": emailAddress }),
})
.then(response => {
if (!response.ok) {
return console.log("Invalid response")
}
else {
console.log("Valid response")
return response.json();
}
})
.then(data => {
if (data) {
console.log(data.error)
}
})
.catch(error => {
console.log(error)
});
}
})
The form:
class CustomerInfoUpdateForm(forms.ModelForm):
class Meta:
model = CustomUser
fields = ["first_name", "last_name", "mobile_number", "email"]
widgets = {
"first_name": TextInput(attrs={"class": "form-control", "id": "account_first_name"}),
"last_name": TextInput(attrs={"class": "form-control", "id": "account_last_name"}),
"mobile_number": NumberInput(attrs={"class": "form-control", "id": "account_phone"}),
"email": EmailInput(attrs={"class": "form-control", "id": "account_email"}),
}
And here is the response from the console: