Nested property access (A pattern / solution)

Maybe I’m practicing an anti-pattern when I do this, but I find myself, client side, doing this a lot for grabbing data for the UI -

local topObject
-- topObject is updated by the server at some point, but for the point of this smaller UI element I only need myData here:   topObject.nextProperty.anotherProperty.againProperty.myData  

if topObject and topObject.nextProperty and topObject.nextProperty.anotherProperty and topObject.nextProperty.anotherProperty.myData then
         print(topObject.nextProperty.anotherProperty.myData)
end

Do you ever find yourself doing this?
Is there a cleaner way to do this in lua?

A couple simple utility functions I was thinking of finally writing since I’ve done this a few dozen times now:

-- returns nil if property is not found, otherwise returns the value of the first property found, recursively
function FindFirstProperty(object, propertyName)
     if object == nil then return end
     for key,value in pairs(object) do
        if key == propertyName then
            return value
        else
            local retVal = FindFirstProperty(object.key, propertyName)
            if retVal then
                return retVal
            end
        end
     end
end
--usage:
local myData = FindFirstProperty(topObject, "myData")

or something cruder like

-- returns nil if any property in the chain is nil
function GetProperty(object, propertyNameList)
     if object == nil then return end
     for _,property in pairs(propertyNameList) do
         if object[property] == nil then return end
         object = object[property]
     end
     return object
end
--usage:
local myData = GetProperty(topObject, {"nextProperty","anotherProperty","myData"})

Thought it was worth running it by the community first, though. If I’m practicing an Anti-Pattern, please call me out & include suggestions to better achieve what I’m trying to achieve.
Or if you know of a lua-specific syntax or helper-function that’d be great too!

PS: I’m not worried if either of my utility functions has errors, was just throwing out some quick untested code for discussion purposes.

2 Likes

I don’t think we have object reflection yet. I wouldn’t worry about it too much–The main thing is that
you are actually checking for nils–A similar form to yours could be:

-- ...
local nextP = topObject and topObject.nextProperty
local anotP = nextP     and nextP.anotherProperty
if anotP  then
    print( anotP.myData )
end
1 Like