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:
- User makes a selection.
- A single
Invoke-RestMethod
gets the data for all items that will appear in the table. Set-UDElement
makes the table appear.- The column I want to update is wrapped in
New-UDDynamic
and is initially populated with the data from the originalInvoke-RestMethod
. - User clicks the Edit button, enters data in the text box, and clicks Submit.
- An
Invoke-RestMethod
updates the item with aPUT
request and a session variable$Session:updateItem
is set to$true
. Sync-UDElement
is triggered for theUDDynamic
in the cell I want to update.- Since
$Session:updateItem
is true, anInvoke-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.