I have some JavaScript fetch()
code that sends data to a MySQL database and prevents a hard page refresh. The backend code is written in PHP. This all works OK, but I decided to change the functions to ES6 arrow functions and an issue has arison around the FormData()
object.
In the code below all of the functions have been changed to arrow functions apart from the function on line 3
.
When I change the one on line 3 to an arrow function i.e. i.addEventListener('submit', (e) => { ...
I get the following error message:
Uncaught TypeError: Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'
...which seems to relate to the this
context?
When I remove this
as a parameter, it throws an error in my PHP and I get Undefined index: create-board-name
in relation to $_POST['create-board-name']
, with 'create-board-name' being the name of the button that submits to the database.
My question is thus, how do I use an arrow function with FormData()
and fetch()
, if the arrow function affects the context of how this
is interpreted?
JavaScript
if (form) {
form.forEach(i => {
i.addEventListener('submit', function(e) {
if (e.submitter && e.submitter.classList.contains('js-fetch-button')) {
e.preventDefault();
var formData = new FormData(this);
formData.set(e.submitter.name, e.submitter.value);
formData.set('json_response', 'yes'); // relates to json encoding in the PHP shown further down
fetch(
theURL, {
method: 'post',
body: formData
})
.then((response) => {
if (response.status === 200) {
response.json().then((json) => {
// --- stuff happens here
});
}
}).catch((error) => {
console.error(error);
})
}
})
})
}
PHP (which I don't think is the issue)
Although I don't think the PHP is the problem I've included it below. Basically when a new board is created it updates the database and then returns this information to the page as JSON so that the new board information can be used immediately after creation if necessary.
// insert into database
$stmt = $connection->prepare(
"INSERT INTO boards (board_name, user_id)
VALUES (:board_name, :user_id )"
);
$stmt->execute([
':board_name' => $create_board_name,
':user_id' => $sessionId
]);
// fetch as JSON
if(isset($_POST['json_response'])) {
$board_stmt = $connection->prepare(
"SELECT * FROM boards
WHERE user_id = :user_id AND board_name = :board_name
ORDER BY board_id DESC"
);
$board_stmt -> execute([
':user_id' => $sessionId,
':board_name' => $create_board_name
]);
$board_row = $board_stmt->fetch();
header('Content-type: application/json');
echo json_encode($board_row);
exit;
}
When you change it to arrow function, this
will be referencing a definition context of the arrow function (class, another function, where you defined that code) instead of the clicked Form element.
How to access form data in arrow function:
i
variable, what you can do then:var formData = new FormData(i);
target
option of the event in the event handler.var formData = new FormData(e.target);