none
V8 web control and jQuery RRS feed

  • Question

  • Hi

    As not all browsers handle async and defer yet, I use simple synchronous loading of the following javascript libs:
    bing, jQuery, "my stuff".

    In the below example, I cannot get the map control to load with jQuery. However, if it type "test()" manually in a dev console, it works.

    I've noticed other forums posts about problems with thenables and promises, but even with the experimental branch, I cannot get it to work. 

    Thanks

    Andrew

     

    <script src="//www.bing.com/api/maps/mapcontrol?branch=experimental"></script> <script src="https://code.jquery.com/jquery-3.1.0.min.js"></script> <script> var test = function () { var map = new Microsoft.Maps.Map('#map_canvas', { credentials: 'secret',                    center: new Microsoft.Maps.Location(54,-1 ),     mapTypeId: Microsoft.Maps.MapTypeId.ordnanceSurvey,   zoom: 14                });  map.setMapType( Microsoft.Maps.MapTypeId.ordnanceSurvey );

    }; jQuery( document ).ready( test );

    </script>


    Gives error messages (in Chrome)

    jQuery.Deferred exception: Microsoft.Maps.Location is not a constructor TypeError: Microsoft.Maps.Location is not a constructor

    Tuesday, August 16, 2016 4:44 PM

Answers

  • All browsers that support HTML5 which is required by V8, support async defer. So there is no reason not to use it.

    As for your issue, jQuery's document ready function will fire way before the map script has had a chance to finish loading. You can still pass in the function name into the map script URL without using async defer and it works fine. If you want to use jQuery to do the loading I would say usin $(window).load(); but it looks like there is a bug in version 3.1 of jquery and this function throws an error about indexOf (even in page that has nothing by jquery in it).


    [Blog] [twitter] [LinkedIn]

    Friday, August 19, 2016 4:47 PM
  • 1) The issue is that jQuery's document ready function fires before the document is fully loaded. This has been an issue with this function for as long as I can remember.

    2) Bing Maps V8 requires HTML5 support. IE9 and below aren't supported browsers and V8 won't work in these. As it is IE10 isn't even documented as a supported browser due to it having a fairly limited set of HTML5 features and is very slow. However V8 does work on IE10 and we don't plan to break it in this browser unless there is a key HTML5 feature we need in the future which IE10 doesn't support.


    [Blog] [twitter] [LinkedIn]

    Wednesday, August 31, 2016 7:45 PM
  • I made the move to using 'defer'. [Aside: so much easier that faffing around with script loading libraries]

    Which gives me this

    <script defer src="//www.bing.com/api/maps/mapcontrol?branch=experimental"></script>
    <script defer src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <script defer src="bootstrap.js">
    <script defer src="my-code.js">

    But you can't use  Bing Maps until *after* the document.ready event ....

    So, my-code.js contains something like

    ready = function() {

    // do everything as normal until ...

    if ( document.readyState == 'complete' ) { load_bing_map( params ); } else { jQuery( window ).on( "load", function() { load_bing_map( params ) } ) } load_bing_map = function ( params ) { // now its safe to use the bing maps api }

    jQuery( ready );


    When the jQuery ready event fires, it runs the ready() function as normal.

    It checks to see if the document-ready-event has already happened.

    => If so, the maps api is safe to use, and load_bing_map() can be run straight away

    => If not, it sets an on_load event to run it instead.

    Note I've used an anonymous function, so it can be passed parameters.

    Thanks for your help, Ricky.


    • Edited by aavmurphy Friday, September 9, 2016 5:23 PM
    • Proposed as answer by Ricky_Brundritt Friday, September 9, 2016 7:32 PM
    • Marked as answer by Ricky_Brundritt Friday, September 9, 2016 7:32 PM
    Friday, September 9, 2016 5:19 PM
  • A better way of doing this is to use a jQuery promise.

    <script defer src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <script defer src="bootstrap.js">
    <script defer src="my-code.js">
    <script defer src="//www.bing.com/api/maps/mapcontrol?branch=experimental?callback=bing8_resolve"></script>

    In the above note that "my-code.js" (which defines the 'bing8_resolve' function) comes before the bing script.

    "my-code.js" contains ...

    // executes on script load, before the 'bing' script loads
    bing8_on_ready = jQuery.Deferred();
    
    // the bing script's callback
    // note: the script name cannot contain '.' (e.g. bing8.resolve))
    bing8_resolve = function () {
      console.info( 'EVENT - bing maps is ready' );
      bing8_on_ready.resolve();
    };
    
    // then, defined a callback function to load the map, 
    // when the promise has been resolved
    
    // if you use functions
    
    jQuery.when( bing8_on_ready ).then(
      function() {
        console.info( 'EVENT display the map' );
        // load the map here ...
        } );
    
    
    // if you use modules
    var this_ = this, params = { option: 'something' } ;
    
    jQuery.when( bing8_on_ready ).then(
      function() {
        console.info( 'EVENT display the map' );
        this_.load_the_map_here( params)
        } );



    • Edited by aavmurphy Tuesday, May 16, 2017 4:04 PM another typo
    • Marked as answer by aavmurphy Tuesday, May 16, 2017 4:43 PM
    Tuesday, May 16, 2017 4:02 PM

All replies

  • All browsers that support HTML5 which is required by V8, support async defer. So there is no reason not to use it.

    As for your issue, jQuery's document ready function will fire way before the map script has had a chance to finish loading. You can still pass in the function name into the map script URL without using async defer and it works fine. If you want to use jQuery to do the loading I would say usin $(window).load(); but it looks like there is a bug in version 3.1 of jquery and this function throws an error about indexOf (even in page that has nothing by jquery in it).


    [Blog] [twitter] [LinkedIn]

    Friday, August 19, 2016 4:47 PM
  • Hi Ricky,

    1)

    You're right. It seems that

    <script src="//www.bing.com/api/maps/mapcontrol?branch=experimental"></script>

    loads things asynchronously, causing my problem.

    If I change my code to use 'async defer', it works fine.

    Might be worth making this clear in the documentation - you can't really load it synchronously with jquery, bootstrap etc. 

    2)

    I had avoided 'async defer' dues to worries about safe browser implementation, especially of the 'defer' part.

    Checking, it seems its only IE9 and below that have problems (IE9 is Vista era).  Checking the stats, they are such a small percentage now, its worth the big performance gain for everyone else to switch

    Thanks

    Andrew


    Wednesday, August 31, 2016 5:31 PM
  • 1) The issue is that jQuery's document ready function fires before the document is fully loaded. This has been an issue with this function for as long as I can remember.

    2) Bing Maps V8 requires HTML5 support. IE9 and below aren't supported browsers and V8 won't work in these. As it is IE10 isn't even documented as a supported browser due to it having a fairly limited set of HTML5 features and is very slow. However V8 does work on IE10 and we don't plan to break it in this browser unless there is a key HTML5 feature we need in the future which IE10 doesn't support.


    [Blog] [twitter] [LinkedIn]

    Wednesday, August 31, 2016 7:45 PM
  • I made the move to using 'defer'. [Aside: so much easier that faffing around with script loading libraries]

    Which gives me this

    <script defer src="//www.bing.com/api/maps/mapcontrol?branch=experimental"></script>
    <script defer src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <script defer src="bootstrap.js">
    <script defer src="my-code.js">

    But you can't use  Bing Maps until *after* the document.ready event ....

    So, my-code.js contains something like

    ready = function() {

    // do everything as normal until ...

    if ( document.readyState == 'complete' ) { load_bing_map( params ); } else { jQuery( window ).on( "load", function() { load_bing_map( params ) } ) } load_bing_map = function ( params ) { // now its safe to use the bing maps api }

    jQuery( ready );


    When the jQuery ready event fires, it runs the ready() function as normal.

    It checks to see if the document-ready-event has already happened.

    => If so, the maps api is safe to use, and load_bing_map() can be run straight away

    => If not, it sets an on_load event to run it instead.

    Note I've used an anonymous function, so it can be passed parameters.

    Thanks for your help, Ricky.


    • Edited by aavmurphy Friday, September 9, 2016 5:23 PM
    • Proposed as answer by Ricky_Brundritt Friday, September 9, 2016 7:32 PM
    • Marked as answer by Ricky_Brundritt Friday, September 9, 2016 7:32 PM
    Friday, September 9, 2016 5:19 PM
  • A better way of doing this is to use a jQuery promise.

    <script defer src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
    <script defer src="bootstrap.js">
    <script defer src="my-code.js">
    <script defer src="//www.bing.com/api/maps/mapcontrol?branch=experimental?callback=bing8_resolve"></script>

    In the above note that "my-code.js" (which defines the 'bing8_resolve' function) comes before the bing script.

    "my-code.js" contains ...

    // executes on script load, before the 'bing' script loads
    bing8_on_ready = jQuery.Deferred();
    
    // the bing script's callback
    // note: the script name cannot contain '.' (e.g. bing8.resolve))
    bing8_resolve = function () {
      console.info( 'EVENT - bing maps is ready' );
      bing8_on_ready.resolve();
    };
    
    // then, defined a callback function to load the map, 
    // when the promise has been resolved
    
    // if you use functions
    
    jQuery.when( bing8_on_ready ).then(
      function() {
        console.info( 'EVENT display the map' );
        // load the map here ...
        } );
    
    
    // if you use modules
    var this_ = this, params = { option: 'something' } ;
    
    jQuery.when( bing8_on_ready ).then(
      function() {
        console.info( 'EVENT display the map' );
        this_.load_the_map_here( params)
        } );



    • Edited by aavmurphy Tuesday, May 16, 2017 4:04 PM another typo
    • Marked as answer by aavmurphy Tuesday, May 16, 2017 4:43 PM
    Tuesday, May 16, 2017 4:02 PM