0

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?

Below the Radar
  • 7,321
  • 11
  • 63
  • 142
  • `this` in your `success` function probably doesn't refer to your `DrilledLayer` object. You can assigned `this` to a local variable, and use that. – forgivenson Oct 10 '14 at 13:32
  • 2
    a) It's async and you're looking too early b) you did get [the `this` context of your callback](http://stackoverflow.com/q/20279484/1048572) wrong – Bergi Oct 10 '14 at 13:32
  • @Bergi: correct, a and b are the answers – Below the Radar Oct 10 '14 at 13:35
  • @BelowtheRadar: For a) you might be interested in [this alternative pattern](http://stackoverflow.com/a/24686979/1048572) for asynchronously initialisiing objects (instead of calling ajax from the constructor) – Bergi Oct 10 '14 at 15:03

1 Answers1

2

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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875