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:
Invoke-RestMethod gets the data for all items that will appear in the table.Set-UDElement makes the table appear.New-UDDynamic and is initially populated with the data from the original Invoke-RestMethod.Invoke-RestMethod updates the item with a PUT request and a session variable $Session:updateItem is set to $true.Sync-UDElement is triggered for the UDDynamic in the cell I want to update.$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
}