Cannot access 'self' from method triggered by handler created within object constructor

Hi Guys,

I’m a new developer here and I’m still evaluating Corona. So far so good but I’ve hit a brick wall.

From everywhere in my object I can access its properties and methods using ‘self’, whether the method is called from within the object or externally. There is a baffling exception to this. When a method is triggered (using ‘self’) from a handler attached to a graphic created within the object, the properties and methods of the object are not available from the called method using ‘self’ even though the method is called successfully.

For example:

MyObject = {}   
   
function MyObject:new( x, y, rotation )  
  
 -- create graphics  
 local image= display.newImage( "image.png" );  
  
 -- place on screen  
 image.x, image.y = x, y  
 image.rotation = rotation;   
  
  
 --create object  
 local object = { test = "RESPONSE" }  
  
 object.image = image;  
  
 setmetatable(object, { \_\_index = MyObject }) -- Inheritance  
  
 --click listener  
 image:addEventListener( "tap", self.click);  
  
 return object;  
  
end  
  
function MyObject:select()  
 print(self.test);  
 return true;  
end  
  
function MyObject:selectObject()   
 self:select();  
end  

I edited this down to simplify the issue. Hopefully I’ve not put in any typos. Basically the issue is that if I click on the image in the object, the ‘select()’ method fires okay but ‘self.test’ prints only ‘nil’. If I point the event handler at 'selectObject() I get an error because the ‘self:select()’ method is evaluating as ‘nil’. But if I run ‘select()’ or ‘selectObject()’ from elsewhere within the object or externally it prints “RESPONSE” As expected.

Am I missing something here? Or is this a bug? [import]uid: 31362 topic_id: 5895 reply_id: 305895[/import]

Line 21 should read

image:addEventListener( "tap", self.select);  

I would fix it but this forum edit page is broken and requires selection from a dropdown which is empty :wink: [import]uid: 31362 topic_id: 5895 reply_id: 20224[/import]

I’ve got this working by putting the select method inside the constructor.

setmetatable(object, { \_\_index = MyObject }) -- Inheritance  
  
function click()  
 print(object.test);  
 return true;  
end  
  
--click listener  
image:addEventListener( "tap", click);  

Something feels a little odd about this though. Is it normal? [import]uid: 31362 topic_id: 5895 reply_id: 20235[/import]

try this. don’t know if it’s the best approach but it works

[lua]MyObject = {}

function MyObject:new( x, y, rotation )

– create graphics
–local image= display.newImage( “image.png” );
local image = display.newRect(0,0,100,100)

– place on screen
image.x, image.y = x, y
image.rotation = rotation;

–create object
local object = { test = ("RESPONSE "…x) }

object.image = image;

– note image is the item clicked, and you want to refer back to object so set a reference
image.myparent = object

setmetatable(object, { __index = MyObject }) – Inheritance

–click listener
image:addEventListener(“tap”,function(event)self:onClick(event)end)

return object;

end

function MyObject:onClick(event)
local imageClicked = event.target
print(imageClicked.myparent.test) – "RESPONSE " etc
return true;
end

local o = MyObject:new(100,100,10)
print("created "…tostring(o))
local o2 = MyObject:new(200,200,45)
print("created "…tostring(o2))[/lua]

or you could do

[lua] image:addEventListener(“tap”,function(event)self:onClick(object)end)[/lua]

then

[lua]function MyObject:onClick(obj)
print(obj.test)
end[/lua]

that works too, although I’m not sure they’re the best approach. i think you’re probably better with your fix, but make it [lua]local function click()[/lua] [import]uid: 6645 topic_id: 5895 reply_id: 20322[/import]

Hi jmp,

Your suggestions solved another new problem I was having :slight_smile: Thanks! I went with the second example because I assume that print(obj.test) would have slightly better performance compared to print(imageClicked.myparent.test) - assuming I’m doing something more complex than printing. Or am I over simplifying?

Thanks again!
Lance [import]uid: 31362 topic_id: 5895 reply_id: 20459[/import]