views:

47

answers:

1

I make an ajax call to retrieve a list and cache is set to true. Later, I insert a new item, and retrieve the list again, but this time I set cache to false. Jquery properly shows me the correct list. It is at this point when I would expect jquery to start caching this updated list with the newly inserted data. However, when I make another call to the list and ask for the cached copy... it shows me the original list without my new data! It has obviously not invalidated the cached data.

Please someone tell me I am screwing something up and the process I describe above is due to a bug in my code.

http://test.virtual-chaos.net/messages/blah

(excuse the language)

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MessageListLoader>" %>
<%@ Import Namespace="GoFuckYourself.Web.Controllers.Messages.ViewModels" %>
<input type="submit" value="Add Message" id="addMessage" />
<% Html.RenderPartial("MessageList", Model.Messages); %>
<input type="submit" value="Previous" id="previousMessages" />
<input type="submit" value="Next" id="nextMessages" />
<div id="messageEditor">
</div>
<div class="messageListLoader">
<script type="text/javascript" id="$">
    var messagesPage = <%: Model.Page %>;

    function clearForm(form) {
        $(form).find(':input').each(function () {
            switch (this.type) {
                case 'password':
                case 'select-multiple':
                case 'select-one':
                case 'text':
                case 'textarea':
                    $(this).val('');
                    break;
                case 'checkbox':
                case 'radio':
                    this.checked = false;
            }
        });
    }

    function postForm(form, trigger) {
        var form = $(form);
        var action = form.attr("action");
        var serializedForm = form.serialize();

        $.post(action, serializedForm, function () {
            clearForm(form);
            $('body').trigger(trigger);
        });
    }

    function cancelForm(trigger) {
        $('body').trigger(trigger);
    }

    function LoadHtml(url, loadFromCache, placeholderid) {
        $.ajax({
            url: url,
            cache: loadFromCache,
            dataType: "html",
            success: function (data) {
                $(placeholderid).replaceWith(data);
            } 
        });
    }

    function LoadMessageList(loadFromCache) {
        var url = '<%: Url.Action("loadpage", "messages", new { CategoryName = Model.Category.CategoryName })%>' + '/' + messagesPage;
        LoadHtml(url, loadFromCache, '#messageList');
    }

    function LoadMessageAdder() {
        var url = '<%: Url.Action("insert", "messages", new { CategoryName = Model.Category.CategoryName }) %>';
        LoadHtml(url, true, '#messageEditor');
    }

    function LoadMessageUpdater(id) {
        var url = '<%: Url.Action("update", "messages", new { CategoryName = Model.Category.CategoryName }) %>' + '/' + id;
        LoadHtml(url, false, '#messageEditor');
    }

    function LoadMessageDeleter(id) {
        var url = '<%: Url.Action("delete", "messages", new { CategoryName = Model.Category.CategoryName }) %>' + '/' + id;
        LoadHtml(url, false, '#messageEditor');
    }

    $('body').bind('messageListRefreshEvent', function (e) {
        LoadMessageList(false);
        $('#messageEditor').text('');
    });

    $('body').bind('messageFormCancelEvent', function (e) {
        $('#messageEditor').text('');
    });

    $('#addMessage').click(function() {
        LoadMessageAdder();
    });

    $('#previousMessages').click(function() {
        messagesPage--;
        if(messagesPage < 0) { messagesPage = 0; }
        LoadMessageList(true);
    });

    $('#nextMessages').click(function() {
        messagesPage++;
        LoadMessageList(true);
    });
</script>

A: 

Correct me if I am wrong:

  1. you make an ajax call to retrieve a list & set cache to true: JQuery receives the response to the call, caches the response and forwards the response to your code.
  2. you insert an item: The previous cached list is still maintained by JQuery and did doesn't have the newly added item
  3. you make an new ajax call to retrieve the list & set the cache to false: JQuery receives the response to the call. Since you told not to cache this call, it just forwards the response to your code. So the cache stills contains the list it got from first call.
  4. you ask for a cached copy: JQuery forwards you the only cached copy it has which is without the newly added item
Shree
yeah that's exactly my process.. I'll try to post some code to clarify.
djmc
this is not just the process that i am explaining here. I am also explaining the internal working of jquery. JQuery is not invalidating your previous cached copy because you didn't tell it to cache the ajax call to retreive the list which has the newly added item. So, I guess, to solve the problem, cache all the ajax calls which is used to retrieve the list so that the latest list overwrites the previous list in the cache.
Shree
If I cache all ajax calls in jquery, how will jquery know when I want an uncached version? There has to be a command to force it to erase its cache and pull a live version.
djmc
I was originally caching all calls like you recommend. That's how I found the problem in the first place. So I changed my logic to turn off caching when I needed a live version.
djmc