Ok, this may sound like a somewhat cryptic title. We are talking about the importance of this, and now I mean the this keyword. To be honest I never worried too much about the this keyword. I know it is a component scope and when you refer to this inside your component, you refer to the public scope, so everything from this component which is visible to the outside world.

But now I had some issues (explanation will follow). I was surprised to see how hard it was to find a decent explanation of the this component scope. Not easy to google, because ‘this’ shows up in a lot of web pages…

So why is it important now? I was rewriting tons of cform code to quick, and for some reason behaviour is a bit different. In cform I had methods in my entity which looked like this:

//cform entity
property name="Product" 
  fieldtype="many-to-one" 
  cfc="Product" 
  fkcolumn="product_id";

public string function getDisplayedId(){
  return getProduct().getCode() & "-" & getId();
}

So just some simple many-to-one relation and a method , retrieve the product in my component, find the code of the product and append the Id of the current object.

Now I do the same in quick using belongsTo for relations:

property name="product_id";
function product() {
  returns belongsTo("Product","product_id")
}
public string function getDisplayedId(){
 return getProduct().getCode() & "-" & getId()
}

This will fail! It tells me getProduct() can not be found in the object. If I resolve this by adding this everything is fine, e.g

property name="product_id";
function product() {
  returns belongsTo("Product","product_id")
}
public string function getDisplayedId(){
 return this.getProduct().getCode() & "-" & getId()
}

Please note: I only prepended this. before getProduct() and not before the getId().

Initially I didn’t understand. But getId() is a getter for the ID property, so this method is always available. getProduct() is a different story. In my cform entity a getProduct method is automatically generated for a many-to-one relation. In my quick entity we just have a product() method, not a getProduct() method. The product method returns a relation, not an object. In quick getProduct() will return the object, but this is depending on a lot of onMissingMethod logic.

OnMissingMethod will make sure the getProduct method will be translated to another call which will return the object, and that’s exactly what makes these cform and quick different. It took some googling, but this is why we need THIS

CFCs are just proxied pages. CreateObject() returns a TemplateProxy that wraps the CFPage that is your actual code.

“myObject.getFoo()”, instead what happens is that it calls a method on the TemplateProxy for invoking a method, which in turn calls the function on the proxied page.

OnMissingMethod handling exists in the invoke() function on the TemplateProxy, thus it only works from outside or through the this scope.

https://stackoverflow.com/questions/17558510/having-to-use-this-scope-with-onmissingmethod-in-extended-class

So because these calls for retrieving my relations only work because of onMissingMethod, we always have to call them internally by using the THIS scope. Quick has a lot of onMissingMethod stuff going on, for example here.

So this is one of the areas where converting cform to quick needs some extra attention. There are more differences which I will address in some future posts, but until now the conversion process is relatively smooth.

Thanks to Adam Cameron and Elliott Sprehn for explaining this in these very old posts: