Apache Cordova
  1. Apache Cordova
  2. CB-491

cordova-1.6.0 + jquery/zepto $(document).bind("deviceready") does not work

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Not a Problem
    • Affects Version/s: 1.6.0
    • Fix Version/s: None
    • Component/s: CordovaJS
    • Labels:
    • Environment:

      Tested on iOS 5.1

      Description

      With Phonegap1.4 or 1.5, I have been OK with the code below, but now I stuck.
      Anyone has an idea? Thanks.
      <html>
      <head>
      <meta name="viewport" content="width=device-width,
      initial-scale=1.0, maximum-scale=1.0, user-scalable=no;"/>
      <meta charset="utf-8">

      <script type="text/javascript" charset="utf-8"
      src="js/cordova-1.6.0.js"></script>
      <script type="text/javascript" src="js/jquery.min.js"></script>
      <script type="text/javascript">

      $(document).ready(function()
      {
      alert("this Alert fires OK");

      $(document).bind("deviceready", function()

      { alert("Got the Error and this Alert Never fires"); }

      );

      });

      </script>

      </head>
      <body>
      <p id="deviceProperties" style="font-size: 20px"></p>
      </body>
      </html>

      (by KenOKABE on https://groups.google.com/forum/?hl=en?hl%3Den&fromgroups#!topic/phonegap/TImcr9kzlq0)

      Possible solution-->

      Hello, I had the same problem with the upgrade from 1.5 to 1.6...

      After a long day I found that that deviceready event begins a little "freak", try changing:

      $(document).bind("deviceready", function()

      { //code });

      by:

      document.addEventListener("deviceready", function()
      { //code }

      , false);

      It worked for me, even so, the most weird thing is that other events like touchmove or orientationchange still works with $( document ).bind; even $( document ).ready function works....

      Appears to fail only with deviceready PG/CV event....

      (by Moisés Gramary Barbosa on same thread)

        Activity

        Hide
        Shazron Abdullah added a comment -

        Can I assume jQuery 1.7.2 or?

        Show
        Shazron Abdullah added a comment - Can I assume jQuery 1.7.2 or?
        Hide
        Moisés Gramary added a comment - - edited

        In my case Zepto 1.0rc1, I tested changing $(document).bind("deviceready"[...] by document.addEventListener("deviceready",[...] and it worked... weird...

        Show
        Moisés Gramary added a comment - - edited In my case Zepto 1.0rc1, I tested changing $(document).bind("deviceready" [...] by document.addEventListener("deviceready", [...] and it worked... weird...
        Hide
        Filip Maj added a comment -

        What if you use bind on deviceready directly instead of nesting it inside the ready callback?

        Show
        Filip Maj added a comment - What if you use bind on deviceready directly instead of nesting it inside the ready callback?
        Hide
        Moisés Gramary added a comment -

        The same thing happens, tested.

        Show
        Moisés Gramary added a comment - The same thing happens, tested.
        Hide
        Filip Maj added a comment -

        It is something to do with jquery/zepto as the vanilla method works.

        We override addEventListener to catch for cordova-specific events (such as deviceready). I've dropped the priority as this is more to do with library interactions than with any specific bug we can identify with cordova at this time.

        Will investigate when I get a chance.

        Show
        Filip Maj added a comment - It is something to do with jquery/zepto as the vanilla method works. We override addEventListener to catch for cordova-specific events (such as deviceready). I've dropped the priority as this is more to do with library interactions than with any specific bug we can identify with cordova at this time. Will investigate when I get a chance.
        Hide
        Moisés Gramary added a comment -

        Ok, I supposed this reading the Cordova-JS lines... I thik the people may be informed for not using $(document).bind("deviceready" in the official docs meantime this is not resolved, because it's not easy to know (I lost my entire day to get the solution of using document.addEventListener("deviceready")... can I help?

        Show
        Moisés Gramary added a comment - Ok, I supposed this reading the Cordova-JS lines... I thik the people may be informed for not using $(document).bind("deviceready" in the official docs meantime this is not resolved, because it's not easy to know (I lost my entire day to get the solution of using document.addEventListener("deviceready")... can I help?
        Hide
        Filip Maj added a comment -

        Sure, if you want to dig into it go for it! Would be nice to figure out why it's not working.

        Show
        Filip Maj added a comment - Sure, if you want to dig into it go for it! Would be nice to figure out why it's not working.
        Hide
        MJ added a comment -

        I see the same issue, after I upgraded from Cordova 1.5 to 1.6, while leaving the rest of my code the same. And I didn't use document.ready at all in my code.

        function onBodyLoad()

        { document.addEventListener("deviceready", onDeviceReady, false); }

        function onDeviceReady()

        { // my code }

        If this issue is not going to be fixed soon, then I'll downgrade back to Cordova 1.5.

        Thanks.

        Show
        MJ added a comment - I see the same issue, after I upgraded from Cordova 1.5 to 1.6, while leaving the rest of my code the same. And I didn't use document.ready at all in my code. function onBodyLoad() { document.addEventListener("deviceready", onDeviceReady, false); } function onDeviceReady() { // my code } If this issue is not going to be fixed soon, then I'll downgrade back to Cordova 1.5. Thanks.
        Hide
        Filip Maj added a comment -

        It's a slippery slope because without zepto it works fine, but with zepto it fails. We do due diligence and not step on anyone's toes in terms of library compliance and playing nice with globals in JS, etc. I am essentially spending time to fix zepto - you can see how this can quickly degenerate. Next you'll want me to optimize your jQuery code

        Like I said, when I have time I'll investigate but this is not a priority for the cordova project. Sorry.

        Show
        Filip Maj added a comment - It's a slippery slope because without zepto it works fine, but with zepto it fails. We do due diligence and not step on anyone's toes in terms of library compliance and playing nice with globals in JS, etc. I am essentially spending time to fix zepto - you can see how this can quickly degenerate. Next you'll want me to optimize your jQuery code Like I said, when I have time I'll investigate but this is not a priority for the cordova project. Sorry.
        Hide
        Moisés Gramary added a comment -

        No, please, focus on optimize your Cordova code

        Show
        Moisés Gramary added a comment - No, please, focus on optimize your Cordova code
        Hide
        Filip Maj added a comment -

        zing!

        Show
        Filip Maj added a comment - zing!
        Hide
        MJ added a comment -

        If this helps: I don't use Zepto. I use JQuery Mobile.

        Thanks.

        Show
        MJ added a comment - If this helps: I don't use Zepto. I use JQuery Mobile. Thanks.
        Hide
        Devin Fallak added a comment - - edited

        This bug is happening to me as well. I followed the Cordova Upgrade Guide to upgrade my project from 1.4.1 to 1.5.0. At this point it was working. Then I upgraded from 1.5.0 to 1.6.0 and I am now getting the same error reported here:
        [INFO] Error in success callback: NetworkStatus0 = TypeError:
        'undefined' is not an object

        Show
        Devin Fallak added a comment - - edited This bug is happening to me as well. I followed the Cordova Upgrade Guide to upgrade my project from 1.4.1 to 1.5.0. At this point it was working. Then I upgraded from 1.5.0 to 1.6.0 and I am now getting the same error reported here: [INFO] Error in success callback: NetworkStatus0 = TypeError: 'undefined' is not an object
        Hide
        Devin Fallak added a comment -

        Also the custom plugins in my project which used to work in 1.5.0 are now undefined.

        Show
        Devin Fallak added a comment - Also the custom plugins in my project which used to work in 1.5.0 are now undefined.
        Hide
        Moisés Gramary added a comment -

        I think your plugins are well, let's say that Cordova is not very well with handling unrecogniced exceptions... try replacing $(document).bind("deviceready"[...] by document.addEventListener("deviceready",[...] and I think that plugins will work too.

        Show
        Moisés Gramary added a comment - I think your plugins are well, let's say that Cordova is not very well with handling unrecogniced exceptions... try replacing $(document).bind("deviceready" [...] by document.addEventListener("deviceready", [...] and I think that plugins will work too.
        Hide
        Devin Fallak added a comment - - edited

        My code actually has been the following since day one:

        document.addEventListener("deviceready",onDeviceReady,false)

        I tried calling this from different places, in body onload, in $(), and just in a <script> tag but none of these fix the problem...

        Show
        Devin Fallak added a comment - - edited My code actually has been the following since day one: document.addEventListener("deviceready",onDeviceReady,false) I tried calling this from different places, in body onload, in $(), and just in a <script> tag but none of these fix the problem...
        Hide
        Moisés Gramary added a comment -

        In that case I recommend you place some alert/console.log starting on the first line of onDeviceReady and moving it along the code until it no appears... but do not believe in "Error in success callback: NetworkStatus0 = TypeError: 'undefined' is not an object" error, because it's wrong. Maybe you are using an undefined variable into a plugin?

        Show
        Moisés Gramary added a comment - In that case I recommend you place some alert/console.log starting on the first line of onDeviceReady and moving it along the code until it no appears... but do not believe in "Error in success callback: NetworkStatus0 = TypeError: 'undefined' is not an object" error, because it's wrong. Maybe you are using an undefined variable into a plugin?
        Hide
        Devin Fallak added a comment -

        Hey you're right, looks like the error happens whenever onDeviceReady throws an exception. Simply commented out all code in the method and the error goes away. Then added code that throws an exception on purpose and I get that error again.

        The code that threw an exception was code that tried to use my custom plugin, but since my custom plugin is undefined I get the error. So since this is technically not the same problem as is reported here I will stop bothering people on this bug thread

        Show
        Devin Fallak added a comment - Hey you're right, looks like the error happens whenever onDeviceReady throws an exception. Simply commented out all code in the method and the error goes away. Then added code that throws an exception on purpose and I get that error again. The code that threw an exception was code that tried to use my custom plugin, but since my custom plugin is undefined I get the error. So since this is technically not the same problem as is reported here I will stop bothering people on this bug thread
        Hide
        Filip Maj added a comment -

        What platforms are all you guys experiencing this problem on? Any specific one or a variety of ones?

        Show
        Filip Maj added a comment - What platforms are all you guys experiencing this problem on? Any specific one or a variety of ones?
        Hide
        Alex C added a comment -

        For me, it's happing on the iPhone. I have not tried it on Android.

        Show
        Alex C added a comment - For me, it's happing on the iPhone. I have not tried it on Android.
        Hide
        Filip Maj added a comment -

        I can confirm the issue with jQuery 1.7.2 on iPhone 5.1 simulator with cordova-1.6.1, with latest master of both native and JS as of today.

        Trying to track it down but have narrowed it down to jQuery. Now diving into the depths of jQuery. Wish me luck!

        Show
        Filip Maj added a comment - I can confirm the issue with jQuery 1.7.2 on iPhone 5.1 simulator with cordova-1.6.1, with latest master of both native and JS as of today. Trying to track it down but have narrowed it down to jQuery. Now diving into the depths of jQuery. Wish me luck!
        Hide
        Filip Maj added a comment -

        Hi everyone,

        Spent a bit of time tracking this one down. I could reproduce the error message on iPhone 5.1:

        [INFO] Error in success callback: NetworkStatus0 = TypeError:
        'undefined' is not an object

        The undefined exception is caused by jQuery event handling code. I dug into jQuery's code and found the root of the problem: when deviceready is internally dispatched in Cordova, it fires all subscribed handlers with no event parameter into the callbacks. It is this detail that trips jQuery up. Specifically, when deviceready is fired, jQuery:

        1. Calls its dispatch function. The first thing this function does is call a fix function that is supposed to normalize the event object parameter being passed into the subscribed handlers.
        2. jQuery passes either the event object parameter, OR window.event (see above link). In cordova's case on the iPhone, both of these are undefined.
        3. If we then take a look at jQuery's fix function, the first thing it does is check the existence of a jQuery.expando property on the passed-in event object. Boom, undefined is not an object.

        So bottom line: jQuery's assumption that all custom events being attached to using bind provide some sort of object into the callback is probably bad. I tried a quick hack/fix by adding another "|| {}" into the parameter short-circuit passed into fix, but that didn't fix the issue completely (no exception was thrown but the deviceready alert still did not fire).

        Sorry folks but this isn't one that cordova can directly fix as it is a jQuery issue. Perhaps if/when we tackle CB-514 then it would resolve this issue as well, but until then, I would recommend filing this as an issue with the jQuery team and hoping something over there can be fixed.

        Show
        Filip Maj added a comment - Hi everyone, Spent a bit of time tracking this one down. I could reproduce the error message on iPhone 5.1: [INFO] Error in success callback: NetworkStatus0 = TypeError: 'undefined' is not an object The undefined exception is caused by jQuery event handling code. I dug into jQuery's code and found the root of the problem: when deviceready is internally dispatched in Cordova, it fires all subscribed handlers with no event parameter into the callbacks. It is this detail that trips jQuery up. Specifically, when deviceready is fired, jQuery: 1. Calls its dispatch function . The first thing this function does is call a fix function that is supposed to normalize the event object parameter being passed into the subscribed handlers. 2. jQuery passes either the event object parameter, OR window.event (see above link). In cordova's case on the iPhone, both of these are undefined . 3. If we then take a look at jQuery's fix function , the first thing it does is check the existence of a jQuery.expando property on the passed-in event object. Boom, undefined is not an object. So bottom line: jQuery's assumption that all custom events being attached to using bind provide some sort of object into the callback is probably bad. I tried a quick hack/fix by adding another "|| {}" into the parameter short-circuit passed into fix , but that didn't fix the issue completely (no exception was thrown but the deviceready alert still did not fire). Sorry folks but this isn't one that cordova can directly fix as it is a jQuery issue. Perhaps if/when we tackle CB-514 then it would resolve this issue as well, but until then, I would recommend filing this as an issue with the jQuery team and hoping something over there can be fixed.
        Hide
        Patrick Mueller added a comment -

        when deviceready is internally dispatched in Cordova, it fires all subscribed handlers with no event parameter into the callbacks. It is this detail that trips jQuery up.

        So, I guess device ready is not being fired from cordova.js, but maybe channel.js? Or somewhere else? Maybe being actually called from bootstrap.js?

        Why can't we just create and pass an event in?

        Wrapping all of our callback firing code in try/catches, with diagnostics printed on errors, would be useful as well. If we only had a good way to report errors before deviceready

        Show
        Patrick Mueller added a comment - when deviceready is internally dispatched in Cordova, it fires all subscribed handlers with no event parameter into the callbacks. It is this detail that trips jQuery up. So, I guess device ready is not being fired from cordova.js , but maybe channel.js ? Or somewhere else? Maybe being actually called from bootstrap.js ? Why can't we just create and pass an event in? Wrapping all of our callback firing code in try/catches, with diagnostics printed on errors, would be useful as well. If we only had a good way to report errors before deviceready
        Hide
        J Barber added a comment - - edited

        I have a project that includes JQuery/JQM on all pages and deviceready fires on some of the pages but not others. Not sure if that's helpful to anyone, will post once I find what the difference is between those that work and those that don't...

        Update: it seems only certain jquery functions cause deviceready to fail. For example empty() doesn't trip up deviceready but getJSON() does.

        Show
        J Barber added a comment - - edited I have a project that includes JQuery/JQM on all pages and deviceready fires on some of the pages but not others. Not sure if that's helpful to anyone, will post once I find what the difference is between those that work and those that don't... Update: it seems only certain jquery functions cause deviceready to fail. For example empty() doesn't trip up deviceready but getJSON() does.
        Hide
        Filip Maj added a comment -

        Can you guys try the 1.7.0rc1 release? There were a bunch of fixes that went into the JavaScript in that release.

        Show
        Filip Maj added a comment - Can you guys try the 1.7.0rc1 release? There were a bunch of fixes that went into the JavaScript in that release.
        Hide
        Kim added a comment -

        Hi,
        I am in the process of adding iPhone support for my app. and I ran into same issue on 1.6.1..
        First I changed the native addEventListener.. that did not work.. but when I rebuild in a 1.7.1rc1 environment.. the event to be fired again.
        Thanks
        Kim

        Show
        Kim added a comment - Hi, I am in the process of adding iPhone support for my app. and I ran into same issue on 1.6.1.. First I changed the native addEventListener.. that did not work.. but when I rebuild in a 1.7.1rc1 environment.. the event to be fired again. Thanks Kim
        Hide
        J Barber added a comment -

        Filip, 1.7.0rc1 works for me. Sweetness and light!

        Show
        J Barber added a comment - Filip, 1.7.0rc1 works for me. Sweetness and light!
        Hide
        Craig Nusinov added a comment - - edited

        Hi, this is my first post and I was kindly referred by Shazron. I upgraded from PG 1.2.0 to Cordova 1.7.0 and having all kinds of issues. I can't seem to find a solution, but first things first - I can not even get a simple date.js file to execute in my index.html file. Here is what I am doing, I know I am probably missing something pretty simple, maybe someone can point me in the correct direction. Thank you! Using Xcode 4.3.2 to compile.

        index.html:

        <!DOCTYPE html>
        <html>
        <head>
        <title></title>

        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
        <meta charset="utf-8">

        <!-- iPad/iPhone specific css below, add after your main css >
        <link rel="stylesheet" media="only screen and (max-device-width: 1024px)" href="ipad.css" type="text/css" />
        <link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="iphone.css" type="text/css" />
        -->
        <!-- If your application is targeting iOS BEFORE 4.0 you MUST put json2.js from http://www.JSON.org/json2.js into your www directory and include it here -->
        <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script>
        <script type="text/javascript" charset="utf-8" src="jquery-1.7.2.min.js"></script>
        <script type="text/javascript" charset="utf-8" src="today.js"></script>

        <script type="text/javascript">

        // If you want to prevent dragging, uncomment this section
        /*
        function preventBehavior(e)

        { e.preventDefault(); }

        ;
        document.addEventListener("touchmove", preventBehavior, false);
        */

        /* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch.
        see http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
        for more details -jm */
        /*
        function handleOpenURL(url)

        { // TODO: do something with the url passed in. }

        */

        function onBodyLoad()

        { document.addEventListener("deviceready", onDeviceReady, false); }

        /* When this function is called, Cordova has been initialized and is ready to roll */
        /* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch.
        see http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html
        for more details -jm */
        function onDeviceReady()

        { // do your thing! navigator.notification.alert("Cordova is working") }

        </script>

        </head>

        <body onload="onBodyLoad()">

        <div id="output"></div><BR><BR>

        <h1>Hey, it's Cordova!</h1>
        <p>Don't know how to get started? Check out our <em><a target="_blank" href="http://docs.phonegap.com/en/edge/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS">Getting Started Guide</a></em>
        <br />
        <ol>
        <li>Check your console log for any white-list rejection errors.</li>
        <li>Add your allowed <strong>hosts</strong> in Cordova.plist/ExternalHosts (wildcards OK, don't enter the URL scheme)</li>
        </ol>
        </body>
        </html>

        today.js - javascript file:

        // today.js
        // This script indicates the current date and time.

        // Call this function when the page has loaded:
        function init() {

        // Want to be strict:
        'use strict';

        // Create a Date object:
        var today = new Date();

        // Create a custom message:
        var message = 'Today is ' + today.toLocaleDateString();

        // Get a reference to the paragraph:
        var output = document.getElementById('output');

        // Update the innerText or textContent property of the paragraph:
        if (output.textContent !== undefined)

        { output.textContent = message; }

        else

        { output.innerText = message; }

        } // End of init() function.

        window.onload = init;

        Show
        Craig Nusinov added a comment - - edited Hi, this is my first post and I was kindly referred by Shazron. I upgraded from PG 1.2.0 to Cordova 1.7.0 and having all kinds of issues. I can't seem to find a solution, but first things first - I can not even get a simple date.js file to execute in my index.html file. Here is what I am doing, I know I am probably missing something pretty simple, maybe someone can point me in the correct direction. Thank you! Using Xcode 4.3.2 to compile. index.html: <!DOCTYPE html> <html> <head> <title></title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" /> <meta charset="utf-8"> <!-- iPad/iPhone specific css below, add after your main css > <link rel="stylesheet" media="only screen and (max-device-width: 1024px)" href="ipad.css" type="text/css" /> <link rel="stylesheet" media="only screen and (max-device-width: 480px)" href="iphone.css" type="text/css" /> --> <!-- If your application is targeting iOS BEFORE 4.0 you MUST put json2.js from http://www.JSON.org/json2.js into your www directory and include it here --> <script type="text/javascript" charset="utf-8" src="cordova-1.8.0.js"></script> <script type="text/javascript" charset="utf-8" src="jquery-1.7.2.min.js"></script> <script type="text/javascript" charset="utf-8" src="today.js"></script> <script type="text/javascript"> // If you want to prevent dragging, uncomment this section /* function preventBehavior(e) { e.preventDefault(); } ; document.addEventListener("touchmove", preventBehavior, false); */ /* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch. see http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html for more details -jm */ /* function handleOpenURL(url) { // TODO: do something with the url passed in. } */ function onBodyLoad() { document.addEventListener("deviceready", onDeviceReady, false); } /* When this function is called, Cordova has been initialized and is ready to roll */ /* If you are supporting your own protocol, the var invokeString will contain any arguments to the app launch. see http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html for more details -jm */ function onDeviceReady() { // do your thing! navigator.notification.alert("Cordova is working") } </script> </head> <body onload="onBodyLoad()"> <div id="output"></div><BR><BR> <h1>Hey, it's Cordova!</h1> <p>Don't know how to get started? Check out our <em><a target="_blank" href="http://docs.phonegap.com/en/edge/guide_getting-started_ios_index.md.html#Getting%20Started%20with%20iOS">Getting Started Guide</a></em> <br /> <ol> <li>Check your console log for any white-list rejection errors.</li> <li>Add your allowed <strong>hosts</strong> in Cordova.plist/ExternalHosts (wildcards OK, don't enter the URL scheme)</li> </ol> </body> </html> today.js - javascript file: // today.js // This script indicates the current date and time. // Call this function when the page has loaded: function init() { // Want to be strict: 'use strict'; // Create a Date object: var today = new Date(); // Create a custom message: var message = 'Today is ' + today.toLocaleDateString(); // Get a reference to the paragraph: var output = document.getElementById('output'); // Update the innerText or textContent property of the paragraph: if (output.textContent !== undefined) { output.textContent = message; } else { output.innerText = message; } } // End of init() function. window.onload = init;

          People

          • Assignee:
            Filip Maj
            Reporter:
            Moisés Gramary
          • Votes:
            4 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 2h
              2h
              Remaining:
              Remaining Estimate - 2h
              2h
              Logged:
              Time Spent - Not Specified
              Not Specified

                Development