Updating data in a single table cell

Product: PowerShell Universal
Version: 4.0.7

I want my users to be able to select an item from a drop-down and have that selection trigger an API request that gets data to populate a table. The table should have a feature to edit the object represented in each row. After editing, I want only that row to update. I have this working in a satisfactory way, but it’s a little janky and I’m wondering if there’s a better approach.

This is what I’m currently doing:

  1. User makes a selection.
  2. A single Invoke-RestMethod gets the data for all items that will appear in the table.
  3. Set-UDElement makes the table appear.
  4. The column I want to update is wrapped in New-UDDynamic and is initially populated with the data from the original Invoke-RestMethod.
  5. User clicks the Edit button, enters data in the text box, and clicks Submit.
  6. An Invoke-RestMethod updates the item with a PUT request and a session variable $Session:updateItem is set to $true.
  7. Sync-UDElement is triggered for the UDDynamic in the cell I want to update.
  8. Since $Session:updateItem is true, an Invoke-RestMethod gets the details of just that item, and the data is updated.
New-UDSelect -Id 'selection' -Label 'Make a selection' -Option {
    New-UDSelectOption -Name 'Option 1' -Value 1
    New-UDSelectOption -Name 'Option 2' -Value 2
    New-UDSelectOption -Name 'Option 3' -Value 3
} -OnChange {
    $Session:optionId = $EventData
    $data = Invoke-RestMethod -Uri "https://example.whatevs/api/v1/things/$($Session:optionId)"

    $columns = @(
        New-UDTableColumn -Property 'Name' -Title 'Name'
        New-UDTableColumn -Property 'Details' -Title 'Details' -Render {
            New-UDDynamic -Id "dyn$($EventData.Name)" -Content {
                $item = $EventData

                if ($Session:updateItem) {
                    $item = Invoke-RestMethod -Uri "https://example.whatevs/api/v1/things/$($Session:optionId)/$($item.Id)"
                    $Session:updateItem = $false
                }

                New-UDTypography -Text "$($item.Details)"
            } -LoadingComponent {
                New-UDSkeleton -Variant rect -Animation wave
            }
        }
        New-UDTableColumn -Property 'Edit' -Title 'Edit' -Render {
            $itemId = $EventData.Id
            $itemName = $EventData.Name

            New-UDButton -Id "btn$($itemName)Edit" -Icon (New-UDIcon -Icon Pencil) -OnClick {
                Show-UDModal -Content {
                    New-UDForm -Id "frm$($itemName)Edit" -Content {
                        New-UDTextbox -Id "txt$($itemName)Edit" -Label 'Details'
                    } -OnSubmit {
                        $Session:updateItem = $true

                        $editDetails = @{
                            Uri = "https://example.whatevs/api/v1/things/$($Session:optionId)/$($itemId)"
                            Method = 'PUT'
                            Body = @{
                                Details = $EventData."txt$($itemName)Edit"
                            }
                        }
                        Invoke-RestMethod @editDetails

                        Sync-UDElement -Id "dyn$($itemName)"

                        Hide-UDModal
                    }
                }
            }
        }
    )

    Set-UDElement -Id 'table' -Content {
        New-UDTable -Data $data -Columns $columns
    }
}

New-UDElement -Id 'table' -Tag 'div'

This works great if the data is in something like New-UDTypography. If I instead put a button in the column and have that button show a modal OnClick, the updated data is displayed the first time you click the button but it reverts to the original EventData on subsequent clicks.

If I lose the $Session:updateItem logic the modal “keeps” the updated data, but the Invoke-RestMethod that gets the updated data will also run on initial table load. If there are 1,000 items, that’s 1,000 extra API calls I don’t need.

I was able to get the update to “stick” by changing the value in $EventData instead of trying to use a separate $item variable.

New-UDDynamic -Id "dyn$($EventData.Name)" -Content {
    if ($Session:updateItem) {
        $item = Invoke-RestMethod -Uri "https://example.whatevs/api/v1/things/$($Session:optionId)/$($item.Id)"

        $EventData.Details = $item.Details
                    
        $Session:updateItem = $false
    }

    New-UDTypography -Text "$($EventData.Details)"
} -LoadingComponent {
    New-UDSkeleton -Variant rect -Animation wave
}