最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Fetch request makes unwanted page reload - Stack Overflow

programmeradmin6浏览0评论

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
Add a comment  | 

2 Answers 2

Reset to default 21

The 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.

发布评论

评论列表(0)

  1. 暂无评论