1

The problem:

fullCalendar does not update events using .fullCalendar('refetchEvents') after succesfull AJAX call.


Using

  • MSIE 11.0.41 (11.0.9600.18638) -- problem occurs
  • FireFox 53.0 (32-bit) -- problem does not occur
  • Chrome 58.0.3029.81 (64-bit) -- problem does not occur

  • VS2015, C# MVC on localhost, IIS Express
  • fullcalendar.js v3.3.0
  • jquery-3.1.1.js
  • jquery-ui-1.12.1.js

Description of symptoms:

When inserting a new event into fullCalendar by using below $.ajax call

$.ajax({
        type: 'POST',
        url: '@Url.Action("SaveEvent","Calendar")',
        data: dataRow,
        success: function (response) {
                 if (response == 'True') {
                    $('#_Calendar').fullCalendar('refetchEvents');
                    alert('New event saved!');
                }
                else {
                    alert('Error, could not save event!');
                }
            }
        });

When the callback comes, the 'refetchEvents' method of fullCalendar will only fire -in MSIE 11- if the debugger/developer window is open. It doesn't matter if there is an actual breakpoint set, only having the debugger/developer window open makes the routine work ?

Even triggering the 'refetchEvents' completely separate from the $.ajax call has the same behaviour. I.E. if I trigger a function as below:

<button type="button" class="btn" onclick="fetchEvents(); return false;">trigger</button>

with function:

function fetchEvents() {
    $('#_Calendar').fullCalendar('refetchEvents');
}

The effect is exactly the same, the 'refetchEvents' will only fire -in MSIE 11- if the debugger/developer window is open ?

I thought it might be a timing problem, hence my manual trigger option, yet the behaviour is the same even though the 'refetchEvents' call is way after the event has been inserted. Even page-refresh does not trigger the 'refetchEvents'the refresh of the events only fires -in MSIE 11- when debugger/developer window is open.

As indicated, no other browser on any platform (that I have tested) has the same result ? (FireFox/Chrome/Safari/Android[Chrome & FireFox] all work flawless...)

Has anybody come across this behaviour and/or potentially have a solution ?

I would appreciate your input !

mtholen
  • 859
  • 6
  • 21
  • This *used* to happen because of this: http://stackoverflow.com/questions/7742781/why-does-javascript-only-work-after-opening-developer-tools-in-ie-once but that should not affect IE11, see the post for suggestions related to caching. – Alex K. May 03 '17 at 15:09
  • Cheers for quick response, I've tried the `$.ajax({cache: false, ...})` option from your suggested post, but no luck... – mtholen May 03 '17 at 15:28

1 Answers1

1

As it turns out it is indeed a caching problem, as per Alex K.'s answer, where IE is too enthusiastic in caching the events for the calendar and does not renew the events.


Solution

In an earlier stage I stumbled across this question and fantastic answer. Somewhat later I also noted this question with an equally good answer. (make sure to upvote them !)

I have combined the two together in one attribute as per below.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
    {
    public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        //Added later from: https://stackoverflow.com/questions/49547/how-to-control-web-page-caching-across-all-browsers
        filterContext.HttpContext.Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        filterContext.HttpContext.Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
        filterContext.HttpContext.Response.AppendHeader("Expires", "0"); // Proxies.

        base.OnResultExecuting(filterContext);
        }
    }

So, by decorating my GetDiaryEvents method with a [NoCache] attribute, the JSON response is appropriately tagged with correct headers, telling the browser NOT to cache the returned values.

Like so:

    //GET: All Diary events
    [NoCache]
    public JsonResult GetDiaryEvents(string start, string end)
        {

        // code code code...

        var rows = eventList.ToArray();
        return Json(rows, JsonRequestBehavior.AllowGet);

        }

And so the JSON message is sent to the browser as:

HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?SDpcTWFydGlqbiBUaG9sZW5cTXkgRG9jdW1lbnRzXFZpc3VhbCBTdHVkaW8gMjAxNVxQcm9qZWN0c1xGaW5pc2hMaW5lXzQuMlxGaW5pc2hMaW5lXzQuMlxDYWxlbmRhclxHZXREaWFyeUV2ZW50cw==?=
X-Powered-By: ASP.NET
Date: Thu, 04 May 2017 09:36:35 GMT
Content-Length: 9265

problem solved...

Community
  • 1
  • 1
mtholen
  • 859
  • 6
  • 21