Below the Radar
Below the Radar

Reputation: 7635

Initializing object with asynchonous request

This is my object definition:

function DrilledLayer(sourceLayerName, sourceTableName, targetLayerName, targetFieldName, operators, baseLayer=false) {
        this.sourceLayerName = sourceLayerName;
        this.sourceTableName = sourceTableName;
        this.targetLayerName = targetLayerName;
        this.targetFieldName = targetFieldName;
        this.operators = operators;
        this.baseLayer = baseLayer;
        this.targetLayerId;
        this.drilledLayerId;
        this.selectedCode;
        this.redraw = false;

        this.getTargetLayerId(); //this function must initialize this.targetLayerId
}

DrilledLayer.prototype.getTargetLayerId = function(){
  $.soap({
    url: 'https://url/version_4.8/services/MapService',
    method: 'getLayersIdByName',
    appendMethodToURL: false,
    data : {
        mapInstanceKey: mapKey,
        layerName: this.targetLayerName,
    },
    error: function(){
        alert("error getLayersIdByName");
    },
    success: function(soapResponse){
        layerId = soapResponse.toJSON().Body.getLayersIdByNameResponse.getLayersIdByNameReturn.getLayersIdByNameReturn.text;
        this.targetLayerId = layerId;
    }
  });
}

This is how I create the object:

drillCs = new DrilledLayer("Drilled CS", "Cs_Franco_General.TAB", "RA_General", "Code_RA", "=")

If I look into drillCs object there is no targetLayerId property defined, but I know the soap request were made successfuly. Why?

Upvotes: 0

Views: 26

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074989

this in JavaScript is mostly set by how a function is called. this during the success callback won't be the same as this during your call to your getTargetLayerId function, you have to remember it.

In this case, the easiest way is probably with a variable:

DrilledLayer.prototype.getTargetLayerId = function(){
  var layer = this;                     // <=== Set it
  $.soap({
    url: 'https://url/version_4.8/services/MapService',
    method: 'getLayersIdByName',
    appendMethodToURL: false,
    data : {
        mapInstanceKey: mapKey,
        layerName: this.targetLayerName,
        },
    error: function(){
        alert("error getLayersIdByName");
     },
    success: function(soapResponse){
        layerId = soapResponse.toJSON().Body.getLayersIdByNameResponse.getLayersIdByNameReturn.getLayersIdByNameReturn.text;
        layer.targetLayerId = layerId; // <=== Use it
        }
    });
}

More (on my blog):

Separately, of course, you won't see the properly until the async callback fires (which will be some time after the new call returns), but you seem to be comfortable with the async aspect of this.

Upvotes: 2

Related Questions