I am running into an issue with a fetch request from my client side to the server. Somehow the fetch request is causing the page to reload, something I want to avoid. I have searched several places in order to figure this one out, but I have to turn to you guys for assistance.
All data transactions between the database is working as expected. Apparently there is no errors in the functionality. Except the fact that I do not want the page to reload on triggering the fetch request.
Note that I am using EJS as a template engine and Bootstrap 4 as a front-end library.
Please have a look at my code below. Any tips in order to avoid the page reload, is much appreciated.
Front-end HTML:
// detailjs.ejs
<div class="row">
<form>
<button class="btn btn-outline-primary" onclick="UpdateArchiveStatus(this)" id="btn-move-to-inbox"><i class="fas fa-inbox"></i> Flytt til innboks</button>
<button class="btn btn-outline-primary" onclick="UpdateArchiveStatus(this)" id="btn-move-to-archive"><i class="fas fa-archive"></i> Arkiver</button>
</form>
</div>
<div class="row">
<input type="hidden" name="resolved-status" id="resolved-status" value="<%= message.status.isResolved %>">
<input type="hidden" name="archive-status" id="archive-status" value="<%= message.status.isArchived %>">
</div>
<!-- Script include --!>
<script src="/assets/js/messages/message-admin.js">
Front-end JavaScript
//message-admin.js
const UpdateArchiveStatus = btn => {
var messageId = $('#message-id').val();
var currentArchiveStatus = $('#archive-status').val();
var newArchiveStatus = null;
if (currentArchiveStatus == 'true') {
newArchiveStatus = false;
} else {
newArchiveStatus = true;
}
StoreArchiveStatus(messageId, newArchiveStatus);
};
function StoreArchiveStatus (messageId, archiveStatus) {
fetch(`/backoffice/api/messages/archive/${messageId}/${archiveStatus}`,
{
method: 'GET',
})
.then(result => {
return result.json();
})
.then(data => {
$('#archive-status').val(data.status);
CheckArchiveStatus();
console.log(data.message);
})
.catch(err => {
console.log(err);
});
};
function ToggleArchivedInterface () {
var inboxButton = $('#btn-move-to-inbox');
var archiveButton = $('#btn-move-to-archive');
inboxButton.removeClass('invisible');
archiveButton.addClass('invisible');
};
function ToggleInboxInterface () {
var inboxButton = $('#btn-move-to-inbox');
var archiveButton = $('#btn-move-to-archive');
archiveButton.removeClass('invisible');
inboxButton.addClass('invisible');
};
async function CheckArchiveStatus () {
var archiveStatus = $('#archive-status').val();
if (archiveStatus == 'true') {
ToggleArchivedInterface();
} else {
ToggleInboxInterface();
}
};
Back-end route:
//routes/backoffice.js
router.get('/api/messages/archive/:messageId/:archiveStatus', authenticate, backofficeController.apiUpdateMessageArchiveStatus);
Back-end controller function:
//controllers/backoffice.js
exports.apiUpdateMessageResolvedStatus = (req, res, next) => {
var messageId = req.params.messageId;
var resolvedStatus = req.params.resolvedStatus;
VisitorMessage.findOneAndUpdate(
{ '_id' : messageId },
{ $set: {
'status.isResolved': resolvedStatus
}
}).then((message) => {
res.status(200).json({message: `Message status was changed`, status: resolvedStatus})
}).catch((err) => {
console.log('The following error occured during update:\n' + err);
res.status(500).json({message: 'An error occured during update.'});
})
};
I am running into an issue with a fetch request from my client side to the server. Somehow the fetch request is causing the page to reload, something I want to avoid. I have searched several places in order to figure this one out, but I have to turn to you guys for assistance.
All data transactions between the database is working as expected. Apparently there is no errors in the functionality. Except the fact that I do not want the page to reload on triggering the fetch request.
Note that I am using EJS as a template engine and Bootstrap 4 as a front-end library.
Please have a look at my code below. Any tips in order to avoid the page reload, is much appreciated.
Front-end HTML:
// detailjs.ejs
<div class="row">
<form>
<button class="btn btn-outline-primary" onclick="UpdateArchiveStatus(this)" id="btn-move-to-inbox"><i class="fas fa-inbox"></i> Flytt til innboks</button>
<button class="btn btn-outline-primary" onclick="UpdateArchiveStatus(this)" id="btn-move-to-archive"><i class="fas fa-archive"></i> Arkiver</button>
</form>
</div>
<div class="row">
<input type="hidden" name="resolved-status" id="resolved-status" value="<%= message.status.isResolved %>">
<input type="hidden" name="archive-status" id="archive-status" value="<%= message.status.isArchived %>">
</div>
<!-- Script include --!>
<script src="/assets/js/messages/message-admin.js">
Front-end JavaScript
//message-admin.js
const UpdateArchiveStatus = btn => {
var messageId = $('#message-id').val();
var currentArchiveStatus = $('#archive-status').val();
var newArchiveStatus = null;
if (currentArchiveStatus == 'true') {
newArchiveStatus = false;
} else {
newArchiveStatus = true;
}
StoreArchiveStatus(messageId, newArchiveStatus);
};
function StoreArchiveStatus (messageId, archiveStatus) {
fetch(`/backoffice/api/messages/archive/${messageId}/${archiveStatus}`,
{
method: 'GET',
})
.then(result => {
return result.json();
})
.then(data => {
$('#archive-status').val(data.status);
CheckArchiveStatus();
console.log(data.message);
})
.catch(err => {
console.log(err);
});
};
function ToggleArchivedInterface () {
var inboxButton = $('#btn-move-to-inbox');
var archiveButton = $('#btn-move-to-archive');
inboxButton.removeClass('invisible');
archiveButton.addClass('invisible');
};
function ToggleInboxInterface () {
var inboxButton = $('#btn-move-to-inbox');
var archiveButton = $('#btn-move-to-archive');
archiveButton.removeClass('invisible');
inboxButton.addClass('invisible');
};
async function CheckArchiveStatus () {
var archiveStatus = $('#archive-status').val();
if (archiveStatus == 'true') {
ToggleArchivedInterface();
} else {
ToggleInboxInterface();
}
};
Back-end route:
//routes/backoffice.js
router.get('/api/messages/archive/:messageId/:archiveStatus', authenticate, backofficeController.apiUpdateMessageArchiveStatus);
Back-end controller function:
//controllers/backoffice.js
exports.apiUpdateMessageResolvedStatus = (req, res, next) => {
var messageId = req.params.messageId;
var resolvedStatus = req.params.resolvedStatus;
VisitorMessage.findOneAndUpdate(
{ '_id' : messageId },
{ $set: {
'status.isResolved': resolvedStatus
}
}).then((message) => {
res.status(200).json({message: `Message status was changed`, status: resolvedStatus})
}).catch((err) => {
console.log('The following error occured during update:\n' + err);
res.status(500).json({message: 'An error occured during update.'});
})
};
Share
Improve this question
edited Mar 6, 2019 at 21:00
Kevin B
95k16 gold badges167 silver badges186 bronze badges
asked Mar 6, 2019 at 20:58
Michael SagnesMichael Sagnes
1091 gold badge1 silver badge6 bronze badges
3
- fetch requests don't cause page reloads. – Kevin B Commented Mar 6, 2019 at 20:59
- 1 Possible duplicate of click event refresh my page – Kevin B Commented Mar 6, 2019 at 21:00
- 2 Yeah, pretty sure since the button is in a form, it's defaulting to a submission. – SpeedOfRound Commented Mar 6, 2019 at 21:03
2 Answers
Reset to default 21The problem is that when your button is clicked, the form is submitting and causing the page to reload.
You can see the problem in action here.
function btnclick(e) {
// comment and uncomment e.preventDefault to see the differences
e.preventDefault()
}
Prevent the default event action and the problem will be solved.
As commented by SpeedOfRound, he is quite right. I did not see this issue myself. Thank you for the help!
Solution:
Remove redundant <form>
tags in the detailjs.ejs
file. These tags caused the page to refresh itself, even though I was using a fetch request.