layer onStatusChanged event not firing since 10.2.6 upgrade

2911
3
Jump to solution
08-22-2015 03:36 PM
AndyWright
Occasional Contributor

Since upgrading to 10.2.6 the onStatusChanged signal for layer objects doesn't seem to be firing.  We have a basemap picker in our app and as the user selected basemaps we would use this event to make sure the basemap they picked was initialized before they could pick any other basemaps.  Not doing that caused an app crash after a while.

I no longer see the onStatusChanged signal in the API documentation for the layer object now, so how can we accomplish this same thing in the new API?  I do still see the same methodology I was using in the Tiled layer online example in the Samples App for 10.2.6, so I'm a little confused as to whether or not this signal is still around in the new version of the API.  Here's some test code you can run to reproduce this issue.  Click each of the buttons to replace the existing basemap and you will see no feedback from the onStatusChanged signal.  This worked like a charm in 10.2.5.

import QtQuick 2.3

import QtQuick.Controls 1.2

import ArcGIS.Runtime 10.26

import ArcGIS.Extras 1.0

ApplicationWindow {

    id: appWindow

    width: 800

    height: 600

    title: "Test"

    Map {

        id: appMap

        anchors.fill: parent

        focus: true

        ArcGISTiledMapServiceLayer {

            url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"

        }

    }

    Button {

        anchors {

            top: parent.top

            right: parent.right

            margins: 10

        }

        text: "Layer 1"

        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer")

    }

    Button {

        anchors {

            top: parent.top

            left: parent.left

            margins: 10

        }

        text: "Layer 2"

        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer")

    }

    Button {

        anchors {

            bottom: parent.bottom

            right: parent.right

            margins: 10

        }

        text: "Layer 3"

        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer")

    }

    Button {

        anchors {

            bottom: parent.bottom

            left: parent.left

            margins: 10

        }

        text: "Layer 4"

        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer")

    }

    function addLayer(url) {

        try {

            var baseLayerToInsert;

            baseLayerToInsert = ArcGISRuntime.createObject("ArcGISTiledMapServiceLayer");

            baseLayerToInsert.url = url;

            bmLyrConnections.target = baseLayerToInsert;

            appMap.insertLayer(baseLayerToInsert, 0);

            appMap.removeLayerByIndex(1);

        }

        catch(err) {

            console.log("BasemapPicker:setBaseLayer" +  err.message);

        }

    }

    Connections {

        id: bmLyrConnections

        onStatusChanged: {

           console.log("BASEMAP STATUS: " + target.status);

           if (target.status === Enums.LayerStatusInitialized) {

               console.log("INITIALIZED");

           }

           else if (target.status === Enums.LayerStatusErrored) {

               console.log(target.error);

           }

        }

    }

}

0 Kudos
1 Solution

Accepted Solutions
LucasDanzinger
Esri Frequent Contributor

Andy,

This looks like a bug. The statusChanged signal does exist, but for some reason it isn't in the doc and it is firing only when initializing, not once it is initialized. I'm also seeing that it works on ArcGISDynamicMapServiceLayer but not ArcGISTiledLayer, so I'm not sure if it is a bug with the layer base class or just with the tiled layer. I have filed a bug to get both the API and doc fixed up.

This is pretty hard to workaround as it is not notifying us when its status changed. The only thing I can think of is to write a short loop to check the status (the status property does work, it is the signal that is not notifying us).  The below code seems to work, however, it is definitely not ideal, as you ideally wouldn't have to write a loop like this whenever you want to switch out a basemap. See line 110 below. You can tweak the number of attempts and wait time to your liking. Again, this isn't an ideal workaround, but you can use it as a base so you aren't completely stuck for the logic you are using.


// Copyright 2015 ESRI
//
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
//
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
//
// See the Sample code usage restrictions document for further information.
//


import QtQuick 2.3
import QtQuick.Controls 1.2
import ArcGIS.Runtime 10.26
import ArcGIS.Extras 1.0




ApplicationWindow {
    id: appWindow
    width: 800
    height: 600
    title: "Test"


    property ArcGISTiledMapServiceLayer baseLayerToInsert


    Map {
        id: appMap
        anchors.fill: parent
        focus: true


        ArcGISTiledMapServiceLayer {
            url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
        }
    }


    Button {
        anchors {
            top: parent.top
            right: parent.right
            margins: 10
        }


        text: "Layer 1"
        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer")
    }


    Button {
        anchors {
            top: parent.top
            left: parent.left
            margins: 10
        }


        text: "Layer 2"
        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer")
    }




    Button {
        anchors {
            bottom: parent.bottom
            right: parent.right
            margins: 10
        }


        text: "Layer 3"
        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer")
    }


    Button {
        anchors {
            bottom: parent.bottom
            left: parent.left
            margins: 10
        }


        text: "Layer 4"
        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer")
    }


    function addLayer(url) {
        baseLayerToInsert = ArcGISRuntime.createObject("ArcGISTiledMapServiceLayer");
        baseLayerToInsert.url = url;


        appMap.insertLayer(baseLayerToInsert, 0);
        appMap.removeLayerByIndex(1);


        console.log(baseLayerToInsert.status)


        var attempts = 0;
        while (baseLayerToInsert.status !== Enums.LayerStatusInitialized && attempts < 10) {
            System.wait(500);
            ++attempts;
        }


        console.log(baseLayerToInsert.status, " === ", Enums.LayerStatusInitialized);
    }
}

View solution in original post

3 Replies
LucasDanzinger
Esri Frequent Contributor

Andy,

This looks like a bug. The statusChanged signal does exist, but for some reason it isn't in the doc and it is firing only when initializing, not once it is initialized. I'm also seeing that it works on ArcGISDynamicMapServiceLayer but not ArcGISTiledLayer, so I'm not sure if it is a bug with the layer base class or just with the tiled layer. I have filed a bug to get both the API and doc fixed up.

This is pretty hard to workaround as it is not notifying us when its status changed. The only thing I can think of is to write a short loop to check the status (the status property does work, it is the signal that is not notifying us).  The below code seems to work, however, it is definitely not ideal, as you ideally wouldn't have to write a loop like this whenever you want to switch out a basemap. See line 110 below. You can tweak the number of attempts and wait time to your liking. Again, this isn't an ideal workaround, but you can use it as a base so you aren't completely stuck for the logic you are using.


// Copyright 2015 ESRI
//
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
//
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
//
// See the Sample code usage restrictions document for further information.
//


import QtQuick 2.3
import QtQuick.Controls 1.2
import ArcGIS.Runtime 10.26
import ArcGIS.Extras 1.0




ApplicationWindow {
    id: appWindow
    width: 800
    height: 600
    title: "Test"


    property ArcGISTiledMapServiceLayer baseLayerToInsert


    Map {
        id: appMap
        anchors.fill: parent
        focus: true


        ArcGISTiledMapServiceLayer {
            url: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
        }
    }


    Button {
        anchors {
            top: parent.top
            right: parent.right
            margins: 10
        }


        text: "Layer 1"
        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer")
    }


    Button {
        anchors {
            top: parent.top
            left: parent.left
            margins: 10
        }


        text: "Layer 2"
        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer")
    }




    Button {
        anchors {
            bottom: parent.bottom
            right: parent.right
            margins: 10
        }


        text: "Layer 3"
        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer")
    }


    Button {
        anchors {
            bottom: parent.bottom
            left: parent.left
            margins: 10
        }


        text: "Layer 4"
        onClicked: addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer")
    }


    function addLayer(url) {
        baseLayerToInsert = ArcGISRuntime.createObject("ArcGISTiledMapServiceLayer");
        baseLayerToInsert.url = url;


        appMap.insertLayer(baseLayerToInsert, 0);
        appMap.removeLayerByIndex(1);


        console.log(baseLayerToInsert.status)


        var attempts = 0;
        while (baseLayerToInsert.status !== Enums.LayerStatusInitialized && attempts < 10) {
            System.wait(500);
            ++attempts;
        }


        console.log(baseLayerToInsert.status, " === ", Enums.LayerStatusInitialized);
    }
}

LucasDanzinger
Esri Frequent Contributor

Along with the below code, you could also add an extra check in the onClicked of the button to actually disable the button

        onClicked: {
            enabled = false
            addLayer("http://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer")
            if (appMap.layerByIndex(0).status)
                enabled = true
        }
0 Kudos
AndyWright
Occasional Contributor

Thanks Luke. That loop will get us past this issue …

0 Kudos