best way to check if dispatchEvent exists?

Hello I have a metatable and on update I’m calling dispatchEvent which works 99% of the time. Every now and then though (according to analytics, we can’t get it to happen locally) it’s saying that it’s a nil value.

if(obj) then obj:dispatchEvent(event) end 

 My assumption is that as long as you have an object you can dispatch and event to it. So by checking if the object exists should take care of that right?

That doesn’t seem to be the case though, and I’m not sure how to check if I can call the dispatchEvent

if (obj.dispatchEvent ~= nil) then obj:dispatchEvent(event) end

Only display objects and the Runtime object have that function.

https://docs.coronalabs.com/api/type/EventDispatcher/dispatchEvent.html

Right, that’s what I meant. What we have it on is a display object. Is there a way to check if it’s a display object? Type() always returns table, and apparently the obj does exist as it gets past our conditional. 

local isDispObj = (obj.numChildren ~= nil)

your wording isn’t clear, which of the following is being reported as nil:  obj, obj.dispatchEvent, or event?

making some assumptions,… my guess would be that you have a “partially torn down object”.  it could be as simple as it’s been display.remove()'d and you’ve just forgotten to release its reference.

local rect = display.newRect(10,10,10,10) rect:dispatchEvent({name="whatever"}) -- WORKS display.remove(rect) if (rect) then -- "rect" is not nil, cuz we forgot to release its reference, but it's not valid! rect:dispatchEvent({name="whatever"}) -- ERROR end

[EDIT] the above code probably won’t actually reproduce your error, consider it “psuedocode” - the point was just to suggest that you check for lingering references[/EDIT]

@horacebury - Thanks, I can’t believe I didn’t think of that simple solution. 

@davebollinger - the event is set above and is always there the obj seems to be set as it passes the conditional but the dispatchEvent is nil. So something is happening (I’m not sure what because over a month of 5 people testing we’ve never had the issue) where the obj is set but it’s changing types from a display object to something else. All I know from the crash reports is obj can’t call dispatchEvent because it’s nil. 

have you ever seen sample code with “seemingly inexplicable” stuff like:

timer.performWithDelay(1, someFunctionThatYoudThinkICouldCallRightNowButDont)

you may be falling victim to this “trickier” sort of partially-torn-down-object syndrome.

the reason people use stuff like the timer code above is that not everything in Corona happens “right now”, and in particular display object removal versus its total destruction are not guaranteed to be synchronous.  (in fact it’s pretty obvious that display.remove() only removes the object from the display list, leaving its proxy scaffolding in place until some “cleanup routine” occurs at the end of current frame - the process is undocumented, but experimentally testable)

so… if you display.remove() something this frame  and attempt to check its properties or call its methods or whatever also in this same frame, you can be fooled into thinking you still have a valid object, when in fact you do not.

and this is exactly the sort of thing, given the proper circumstances, that can work 99% of the time, but with just a tiny bit of “odd timing” (say you’re emitting messages in an enter frame loop, but destroying object based on touch events, or maybe there’s a transition onComplete in there, or a timer, or etc - so that the two might be a frame +/- of each other) you can get that sort of occassional “1%” failure.

if (obj.dispatchEvent ~= nil) then obj:dispatchEvent(event) end

Only display objects and the Runtime object have that function.

https://docs.coronalabs.com/api/type/EventDispatcher/dispatchEvent.html

Right, that’s what I meant. What we have it on is a display object. Is there a way to check if it’s a display object? Type() always returns table, and apparently the obj does exist as it gets past our conditional. 

local isDispObj = (obj.numChildren ~= nil)

your wording isn’t clear, which of the following is being reported as nil:  obj, obj.dispatchEvent, or event?

making some assumptions,… my guess would be that you have a “partially torn down object”.  it could be as simple as it’s been display.remove()'d and you’ve just forgotten to release its reference.

local rect = display.newRect(10,10,10,10) rect:dispatchEvent({name="whatever"}) -- WORKS display.remove(rect) if (rect) then -- "rect" is not nil, cuz we forgot to release its reference, but it's not valid! rect:dispatchEvent({name="whatever"}) -- ERROR end

[EDIT] the above code probably won’t actually reproduce your error, consider it “psuedocode” - the point was just to suggest that you check for lingering references[/EDIT]

@horacebury - Thanks, I can’t believe I didn’t think of that simple solution. 

@davebollinger - the event is set above and is always there the obj seems to be set as it passes the conditional but the dispatchEvent is nil. So something is happening (I’m not sure what because over a month of 5 people testing we’ve never had the issue) where the obj is set but it’s changing types from a display object to something else. All I know from the crash reports is obj can’t call dispatchEvent because it’s nil. 

have you ever seen sample code with “seemingly inexplicable” stuff like:

timer.performWithDelay(1, someFunctionThatYoudThinkICouldCallRightNowButDont)

you may be falling victim to this “trickier” sort of partially-torn-down-object syndrome.

the reason people use stuff like the timer code above is that not everything in Corona happens “right now”, and in particular display object removal versus its total destruction are not guaranteed to be synchronous.  (in fact it’s pretty obvious that display.remove() only removes the object from the display list, leaving its proxy scaffolding in place until some “cleanup routine” occurs at the end of current frame - the process is undocumented, but experimentally testable)

so… if you display.remove() something this frame  and attempt to check its properties or call its methods or whatever also in this same frame, you can be fooled into thinking you still have a valid object, when in fact you do not.

and this is exactly the sort of thing, given the proper circumstances, that can work 99% of the time, but with just a tiny bit of “odd timing” (say you’re emitting messages in an enter frame loop, but destroying object based on touch events, or maybe there’s a transition onComplete in there, or a timer, or etc - so that the two might be a frame +/- of each other) you can get that sort of occassional “1%” failure.