Kendo UI datasource - beforeSend with async/await

1.3k Views Asked by At

Originally I use setRequestHeader() in kendo UI datasource's beforeSend event to set the bear token in the http header and it works great.

Now, in order to handle the token timeout issue, I would like to refresh the token in beforeSend event. But because Fetch is an async function so the event beforeSend will return immediately so the kendo datasource used the old token and then got 401 finally.

I checked that beforeSend doesn't support async so any idea could achieve this purpose?

Updated

As recommended I used ajaxSend() which will be called everytime a ajax call is invoked. Inside ajaxSend(), I use fetch (cross domain) to refresh the token so that the next ajax call will use a new token in the request header:

$(document).ajaxSend(function (e, xhr, options) {
    console.log('Event: ', e);
    console.log('xhr: ', xhr);
    console.log('Options: ', options);

    console.log('Old access_token: ', my_user.access_token);

    let formData = 'grant_type=refresh_token&refresh_token=' + my_user.refresh_token;

    fetch('url/Token', {    //---cross domain server
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded'},
        body: formData })
    .then(data => data.json())
    .then(user => {
        if (user.access_token) {
            xhr.setRequestHeader('Authorization', 'Bearer ' + user.access_token);

            console.log('New access_token: ', user.access_token);
        }
        else {
            console.error('error');
        }
    }).catch(error => {
        console.error(error.message);
    })
});

But strangely, don't know why the coming ajax call still used 'Old access_token' rather than 'New access_token'.

2nd Update

I found out ajaxSend doesn't support async either.

There is another post has the same question with mine. jQuery: how to make ajaxSend wait for another Ajax response before proceeding?

The answer in that post suggested that instead of making the original ajax request to wait, another approach is to abort the original request and retry the request after the async call (mine is fetch) completed. I have such idea before but it doesn't suit for my case because I am using Kendo UI grid to wait for the response then the grid will be auto updated. If I abort the original request and retry it, the Kendo UI grid won't be updated automatically because the request was aborted. Unless I update the Kendo grid by code manually but it's not my intention.

1

There are 1 best solutions below

1
dev_in_progress On

You can try to intercept requests with ajaxSend.

$(document).ajaxSend(function (e, xhr, options) {
    console.log('Event: ', e);
    console.log('xhr: ', xhr);
    console.log('Options: ', options);

    xhr.setRequestHeader('Authorization', 'Bearer ' + 'jwt');
});

This will intercept every request. I tested it with read and fetch dataSource methods.

.ajaxSend()

Note: As of jQuery version 1.8, this method should only be attached to document.