How to wrap this code into a function?

I am attempting to convert the following code into a function:

New-UDTableColumn -Property CPU -Title "CPU (%)" -Render {
            New-UDElement -tag div -Content {
                if ([string]::IsNullOrEmpty($EventData.CPU) -eq 'True' ) {
                    New-UdTypography -Text "No Data"
                }
                elseif ($EventData.CPU -gt 90) {
                    New-UDTooltip -TooltipContent { "CPU is currently at: " + [String]$EventData.CPU +"%!" } -Content { 
                        New-UDIcon -Icon exclamationtriangle -Size 2x -Color red
                    }
                    if((Get-UDElement -Id 'AlertsSwitch').checked -eq 'True'){
                    $Body = [String]$EventData.ServerName + " CPU is currently at: " + [String]$EventData.CPU +"%!"
                    Show-UDToast -Message $Body -BackgroundColor red -MessageColor white -Duration 30000
                    }
                    
                }
                elseif ($EventData.CPU -gt 70) {
                    New-UDIcon -Icon exclamationtriangle -Size 2x -Color orange
                } else {
                    New-UDIcon -Icon checkcircle -Size 2x -Color green
                }
            }

I have many different columns similar to this, which is why I am trying to turn it into a function so I can make the code of my dashboard easier to understand and maintain. Here is what I pass in to call my custom function:

New-MainTableColumn -ColumnProperty 'CPU' -ColumnTitle 'CPU(%)' -ThresholdOne 40 -ThresholdTwo 50 

…And here is the function code itself that dynamically creates the column:

function New-MainTableColumn {
    param($ColumnProperty, $ColumnTitle, $ThresholdOne, $ThresholdTwo)

    $Cache:ColumnProperty = $ColumnProperty
    $Cache:ThresholdOne = $ThresholdOne
    $Cache:ThresholdTwo = $ThresholdTwo
    

New-UDTableColumn -Property "$ColumnProperty" -Title "$ColumnTitle" -Render {
    New-UDElement -tag div -Content {
        $ColumnProperty = $Cache:ColumnProperty
        $ThresholdOne = $Cache:ThresholdOne
        $ThresoldTwo = $Cache:ThresholdTwo 

        #Display No Data warning on dashboard
        if ([string]::IsNullOrEmpty($EventData.$ColumnProperty) -eq 'True' ) {
            New-UdTypography -Text "No Data"
        }
        elseif ($EventData.$ColumnProperty -gt $ThresoldTwo) {
            New-UDTooltip -TooltipContent { "$ColumnProperty is currently at: " + [String]$EventData.$ColumnProperty } -Content { 
                New-UDIcon -Icon exclamationtriangle -Size 2x -Color red
            }
            if((Get-UDElement -Id 'AlertsSwitch').checked -eq 'True'){
            $Body = [String]$EventData.ServerName + " $ColumnProperty is currently at: " + [String]$EventData.$ColumnProperty
            Show-UDToast -Message $Body -BackgroundColor red -MessageColor white -Duration 3000
            }
        }
        elseif ($EventData.$ColumnProperty -gt $ThresholdOne) {
            New-UDTooltip -TooltipContent { " $ColumnProperty is currently at: " + [String]$EventData.$ColumnProperty } -Content { 
                New-UDIcon -Icon exclamationtriangle -Size 2x -Color Orange
            }
        } else {
            New-UDTooltip -TooltipContent { " $ColumnProperty is currently at: " + [String]$EventData.$ColumnProperty } -Content { 
                New-UDIcon -Icon checkcircle -Size 2x -Color green
            }
        }
    }
}
}

My issue is that as soon as I add an additional function call like so:

 New-MainTableColumn -ColumnProperty 'CPU' -ColumnTitle 'CPU(%)' -ThresholdOne 40 -ThresholdTwo 50 
        New-MainTableColumn -ColumnProperty 'FailedJobs_Count' -ColumnTitle 'Failed Jobs' -ThresholdOne 40 -ThresholdTwo 50 

…It seems that the table actually renders both column, but the values themselves both show data for the last function call parameters passed in:
image

So obviously it seems that whatever the last function call is… is actually what is cached and everything before that is overwritten. I’ve tinkered around with ideas about setting variables dynamically, but I am still falling short on how to accomplish this or if it is even a good idea to do so.

One of things I like to do when working with Icons like you are is to set them all as Session variables within my pages code just to make it easier to call them and it shortens your actual code base quite a bit. Another thing you can try here is to loop through your data in each column declaration and that may solve your rendering problem. I’m not at a place to run the code myself but just looking at it that seems like a viable solution.

Can you elaborate on what you mean by setting your icons to session variables? What I don’t show in my code pasted above is that I did turn some of the lines into functions like so:

New-UDIcon -Icon checkcircle -Size 2x -Color green

This allows me to simply call something like New-GreenCheckMark -myValue "$($EventData.CPU)". While this does not shorten my code base a whole lot, it does allow me to change the icons for all my columns at once versus doing every one of them individually. Are you proposing a similar solution?

It’s funny you recommend a loop as I was thinking the same thing, but the issue is that it is difficult to visualize what $EventData looks like at the time the table is rendered. Also, because my column names are unique (i.e. Blocking, Deadlocking, CPU, etc) I am not sure how I would match the name up to the column itself if that makes sense. It seems like no matter what I do I am going to have to implement some sort of naming standard to get this to be dynamic, but the issue I am really struggling with is the context here.

When I establish all my columns and add them to the array, the column/row values themselves are not “rendered” until my data is populated. I have never used debugging in PSU, but maybe I need to give it a shot?

Thats a much more elaborate (and genius) way to handle icons than I was thinking most of the time I just set mine to something like $Session:icon = New-UDIcon -Icon checkcircle -size 2x -Color green then I just call to that variable in the script to load the icon. I’ve never thought about a function to handle icons I might have to try that out myself.

In terms of how you’re building the columns currently if you aren’t sure how the eventdata will look when you process or build the table maybe building an array of PSObjects you can loop through might be worth a shot? I’ve done that in the past for Tables and it always seemed to be alot less clunky than trying to manually process data into the Table.

That is precisely what I am doing so I’m not sure what you mean or how that helps my situation. Can you elaborate?