locked
need help with bing map js widget RRS feed

  • Question

  • Following along with this blog post, I was able to get the map up and running. The problem is that that the push pins randomly show up (or don't show up).  Say, you have 3 addresses in the collection, when the page loads there might be 3 pins, refresh the browser and there might be one pin, refresh again 3 pins, refresh again 2 pins. My first attempt to fix it was to make double triple sure the data from the collection was loaded before attempting to render the pins.  I'm sure that is the case, so I think the issue is that the "addPinAsync" method is trying to add the pins whether the data has completely returned from the service or not, thus the seemingly random appearance of the pins.  Sometimes it is fast enough and the data is there, sometimes not.  Anyone know how to fix it?  My code is below.  I did not alter the js file from the blog post.  Thanks!

    /// <reference path="~/GeneratedArtifacts/viewModel.js" />
    
    myapp.BrowseAddresses.Addresses_render = function (element, contentItem) {
        var mapDiv;
        var current = 0;
        var step;
    
        mapDiv = $('<div />').appendTo($(element));
        $(mapDiv).lightswitchBingMapsControl();
        $(mapDiv).find(":button").attr('data-role', 'none'); // added to remove annoying button
    
        contentItem.screen.getAddresses().then(function (addresses) {
            if (addresses.isLoaded) {
                var data = addresses.data;
                step = data.length;
                showItems(current, step, data);
            } else { // not necessary but just in case for troubleshooting
                console.log('unloaded');
                addresses.load().then(function (addresses) {
                    var data = addresses.data;
                    step = data.length;
                    showItems(current, step, data);
                });
            }
    
        });
        
        // removed this in favor of manually loading the data for troubleshooting
    
        //var visualCollection = contentItem.value;
        //if (visualCollection.isLoaded) {
        //    console.log(visualCollection.isLoaded);
        //    showItems(current, step, contentItem.screen);
        //} else {
        //    visualCollection.addChangeListener("isLoaded", function () {
        //        showItems(current, step, contentItem.screen);
        //    });
        //    visualCollection.load();
        //}
    
        function showItems(start, end, data) {
            $(mapDiv).lightswitchBingMapsControl("resetMap");
            $.each(data, function (i, address) {
                var addressValue,
                    cityValue,
                    countryValue;
    
                // just to make sure data is loaded.
                var address1 = address.getAddress1().then(function (value) {
                    addressValue = value;
                });
                var city = address.getCity().then(function (value) {
                    cityValue = value;
                });
                var country = address.getCountry().then(function (value) {
                    countryValue = value;
                });
    
                WinJS.Promise.join(address1, city, country).then(function () {
                    //if (i >= start && i <= end) {
                    console.log(address1);
                    // this has to be the problem??
                    $(mapDiv).lightswitchBingMapsControl("addPinAsync", addressValue,
                                cityValue, countryValue, i + 1, function () {
                                    //screen.Addresses.selectedItem = address;
                                    //screen.showPopup("Details");
                                });
    
                    //}
                });
            });
        }
    };



    • Edited by Hessc Friday, June 19, 2015 5:05 PM
    Friday, June 19, 2015 4:48 PM

Answers

  • The problem was indeed null values in my data.  Adding the check noted below solved the problem.  This is a mock up but you get the idea.  Joining the promises as suggested by ChrisCookDev was also a big help.

    function showItems(start, end, data) {
            $(mapDiv).lightswitchBingMapsControl("resetMap");
            $.each(data, function (i, address) {
                var addressValue,
                    cityValue,
                    countryValue;
    
                // just to make sure data is loaded.
                var address1 = address.getAddress1().then(function (value) {
                // add this check to each value
                if (value !== undefined && value !== null) {
                    addressValue = value;
                } else {
                    addressValue = "";
                }
                });
                var city = address.getCity().then(function (value) {
               if (value !== undefined && value !== null) {
                    cityValue = value;
               } else {
                    cityValue = "";
               }
                });
                var country = address.getCountry().then(function (value) {
                if (value !== undefined && value !== null) {
                    countryValue = value;
                } else {
                    countryValue = "";
                }
                });
    
                WinJS.Promise.join(address1, city, country).then(function () {
                    //if (i >= start && i <= end) {
                    console.log(address1);
                    // this has to be the problem??
                    $(mapDiv).lightswitchBingMapsControl("addPinAsync", addressValue,
                                cityValue, countryValue, i + 1, function () {
                                    //screen.Addresses.selectedItem = address;
                                    //screen.showPopup("Details");
                                });
    
                    //}
                });
            });
        }
    

    • Marked as answer by Hessc Sunday, June 21, 2015 7:12 PM
    Sunday, June 21, 2015 7:11 PM

All replies

  • Is there the possibility that your not storing your values in the session? So every time you refresh, you get different values based on your asynchronous call?

    Might be worth checking that. Also, adding a callback to your function below code get you more information:

    $(mapDiv).lightswitchBingMapsControl("addPinAsync", addressValue,
                                cityValue
    , countryValue, i + 1, function () {
                                   
    //screen.Addresses.selectedItem = address;
                                   
    //screen.showPopup("Details");
                               
    });

    Friday, June 19, 2015 5:11 PM
  • Hi Juan, I'm not storing the values in the session.  The variable values should all reset each time the page is refreshed, correct?  When they reset, everything should work.  I can log all my values and the correct data shows up from the collection every time.  What do think might be happening based on the async calls?  I will try a callback.  The callback in the function that is commented out (setting the selected item value to the value of the clicked pin) works for the pins that are actually rendered.  I commented them out just to remove unnecessary code while troubleshooting.  Appreciate any further ideas you migh have.  Thanks!
    Friday, June 19, 2015 5:34 PM
  • Well, I am thinking if your not working with a session, there is no way keep track of the values. To save the extra work or trouble, a callback I think should help, at least you can get more information about what your callbacks are doing when they are complete.

    Yeah, with the refresh your values should reset, though this might apply to creating a session each time you render, refreshing the session should also clear your data, so the values you expect to appear each time are more accurate.

    Are you referring to your addPinAsync with the Maps Control?

    Not sure what your function getAddress1(), getCity(), getCountry() is doing, I suspect that your just storing the values for use for rendering the pins at the end.

    This also might be useful for checking:

    I gathered if you use a listener such as

    var pin = document.querySelector('.pin');

    pin.addEventListener('load', function() {

    // expected pin loaded!

    });

    Not sure what the DOM will show for pin element, so if  '.pin' is wrong I apologize, might want to do a F12 and bring up the developer tools and check.

    Or if you use jQuery, you could use .on, just having some validation there would probably help narrow it down.

    Hope that helps! More info here:

    http://www.html5rocks.com/en/tutorials/es6/promises/

    http://api.jquery.com/on/


    • Edited by Juan Davila Friday, June 19, 2015 7:46 PM Added other functions for obtaining values.
    Friday, June 19, 2015 7:45 PM
  • Thanks for your help, I will try those ideas.  I would also still like to here from anyone that is using bing maps in production.

    • Edited by Hessc Friday, June 19, 2015 7:54 PM
    Friday, June 19, 2015 7:49 PM
  • The problem was indeed null values in my data.  Adding the check noted below solved the problem.  This is a mock up but you get the idea.  Joining the promises as suggested by ChrisCookDev was also a big help.

    function showItems(start, end, data) {
            $(mapDiv).lightswitchBingMapsControl("resetMap");
            $.each(data, function (i, address) {
                var addressValue,
                    cityValue,
                    countryValue;
    
                // just to make sure data is loaded.
                var address1 = address.getAddress1().then(function (value) {
                // add this check to each value
                if (value !== undefined && value !== null) {
                    addressValue = value;
                } else {
                    addressValue = "";
                }
                });
                var city = address.getCity().then(function (value) {
               if (value !== undefined && value !== null) {
                    cityValue = value;
               } else {
                    cityValue = "";
               }
                });
                var country = address.getCountry().then(function (value) {
                if (value !== undefined && value !== null) {
                    countryValue = value;
                } else {
                    countryValue = "";
                }
                });
    
                WinJS.Promise.join(address1, city, country).then(function () {
                    //if (i >= start && i <= end) {
                    console.log(address1);
                    // this has to be the problem??
                    $(mapDiv).lightswitchBingMapsControl("addPinAsync", addressValue,
                                cityValue, countryValue, i + 1, function () {
                                    //screen.Addresses.selectedItem = address;
                                    //screen.showPopup("Details");
                                });
    
                    //}
                });
            });
        }
    

    • Marked as answer by Hessc Sunday, June 21, 2015 7:12 PM
    Sunday, June 21, 2015 7:11 PM