0

Update I realize this question is difficult to follow given the implementation. To see and test a working sample please download the solution.

To test you must use IE9 and the development tools cannot be open. Opening the dev tools will cause the project to work as expected. This solution works fine with any other browser. For testing I setup the solution locally within IIS and ran it outside of VS /debug.


I have a project where I am trying to save a knockout observable back to the sever. I am seeing some really strange things in IE9 that I cannot explain and I am hoping someone can help me out. I am using Asp.NET Mvc along with knockout and have implemented the JS revealing module pattern for this part of the project. my js files are as follows:

  • Reportwriter.js basic binding to html for revealing pattern
  • ReportWriterEffects.js this contains any events that the UI generates that are passed to the knockout Viewmodel
  • ReportWriterUtilities.js. This contains the functions for data/object manipulation within the Viewmodel
  • ReportWriterViewModel.js Reportwriter viewmodel Json serialization/ serialization.

My html page has the following element

<a id="footerSaveButton" class="blackGradient panelBtn pleft" >

When this is clicked a non-obtrusive event is called from within the ReportWriterEffects.js

 $(document).on({

            click: function () {
                alert('click');// placed here for testing
                var context = ko.contextFor(this);
                context.$root.Save();
            }
        }, '#footerSaveButton');

This should in turn call from ReportWriterViewModel.js which looks like

self.Save = function () {
            if (self.ValidateReport()) {

                // Transform the custom types in the myFilters collection into the form required by the server-side representation.
                self.TransformFilters();
                ReportWriterUtilities.Save(self.iqReport);
            }

which passes my report observable to the reportWriterUtilities.js file where the ajax call is made

function Save(reportObservable) {
  // Determine which method to call based upon the state of report modification.
  var command = reportObservable().IsNewReport() ? "SaveNewReport" : "UpdateExistingReport";
$.ajax({
    type: "POST",
    url: "../" + command,
    data: "{ json:'" +
    ko.toJSON(reportObservable, function (key, value) { // Remove the __type attribute. This causes problems with deserialization.
        if (key == "__type") {
            return;
        }
        else {
            return value;
        }
    }) + "'}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    cache: false,
    success: function (msg) {
        if (msg.Key != null) {
            // Update the ViewModel with properties from the saved Report.
            reportObservable().ReportId(msg.Key.ReportId);
            reportObservable().DateLastModified(msg.Key.DateLastModified);

            AlertMessaging.DisplaySuccess("Report Saved!", 'Your Report has been saved and is available in your Report Library. <i><a target="_self" href="../../ReportLibrary">Go to Report Library</a></i>');
        }
        else {
            // Display an error with the given text.
            AlertMessaging.DisplayError("Problem Saving Report", msg.Value);
        }
    }, error: function (err) {
        AlertMessaging.DisplayError("Error Saving Report", "The Server returned an error code. Code: " + err.status);
    }
    });
}

In Firefox and Chrome this all works and the report is saved. However within IE the save call is never invoked. I originally had a knockout bind set on the <a> element which was never invoked. I thought the browser cache may have been having an impact on this since I was using Mvc so I decorated the controller to not load cache by adding the following attribute to the controllers constructor

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public class ReportLibraryController : RootController
{ ...

Still no dice.

If you look to the ajax calls you will also see where I added cache: false thinking that may help. Still nothing.

I added the alert message and that does get called but the context.$root.Save(); is never called.

Now here is the really weird thing. When I load the page in IE9 and press F12 to open the dev tools in IE and then close the dev tools the save function within the viewmodel is called and everything works. If I launch the browser open dev tools and navigate to the page everything works. No errors or messages are generated in the console and it all works fine within other browsers. This seems isolated to IE9 as IE 10 works fine.

Does anyone have any suggestions or have you experienced any thing like this in the past. I'd appreciate any insight into what may be causing this to occur. I hope the code below will suffice. I can't use fiddle since I am using the revealing pattern here and it doesn't give accurate representation of the code.

rlcrews
  • 3,182
  • 15
  • 63
  • 109

1 Answers1

4

In IE8&9, console is undefined whenever F12 developer tools have not been initialized for the current document (afaik, old versions of firebug suffered from this as well).

Your self.Save seems to fail on console.log('VM reached'); in ReportWriterViewModel.js(13). There could be other places as well, but this is as far as my artisan static code analysis gets me (no access to a VisualStudio IDE... or trust for unverified solutions :)

You could just continue developing business-as-usual with developer tools open, as long as console calls are stripped from production code - this would be my personal preference.

Alternatively, you could choose to "plug" console methods with a noop (a method that does nothing):

/*https://stackoverflow.com/a/9593812/1081234*/
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };

This answer deserves attention as well, since it plugs other console methods.

Community
  • 1
  • 1
Oleg
  • 22,838
  • 4
  • 55
  • 82
  • @ o.v that was the issue. Nested within one of my validation functions I had a console.log event. Never would have thought that to be the issue but it was. Thanks for the insight on console being undefined in those versions of the browser – rlcrews Nov 25 '13 at 16:27
  • @rlcrews: I'm glad to hear this helped. We've run into a similar issue a while back and it seems like MSDN is *still* being obscure about this and other issues. IMHO, it's fascinating how many developers are buying into the whole *"IE9+ is such a great browser!"* marketing campaign. – Oleg Nov 26 '13 at 00:29