Creating a function in a module, with multiple return statements

I’m trying to make a confirm modal module for my PSU dashboard, but pretty sure it’s a powershell problem I’m having and not a Dashboard problem.

My module function looks like this so far:

function New-UDConfirm {
    <#
    .SYNOPSIS
    Shows a confirm object in a modal, returns either true or false.
    
    .DESCRIPTION
    Shows a confirm object in a modal, returns either true or false.
    #>
    [CmdletBinding()]
	param(
		[Parameter(Mandatory = $false,
				   ValueFromPipeline = $true,
				   ValueFromPipelineByPropertyName = $true)]
		[string]$Text = 'Are you sure?'
	)
    Show-UDModal -Content {
        New-UDTypography -Text $Text
    } -Footer {
        New-UDButton -Text "Yes" -OnClick {
            Hide-UDModal
            return $true
        } -Style @{"border-radius" = "4px"}

        New-UDButton -Text "No" -OnClick {
            Hide-UDModal
            return $false
        } -Style @{"border-radius" = "4px"}

    } -Persistent
}

But even before any of the buttons is clicked, the function returns a null value.
I only started learning PS about a year ago, so I guess this is just some easy fix i didn’t catch about modules yet.

You currently can’t return stuff from event handlers like this. Try something like this.

function New-UDConfirm {
    <#
    .SYNOPSIS
    Shows a confirm object in a modal, returns either true or false.
    
    .DESCRIPTION
    Shows a confirm object in a modal, returns either true or false.
    #>
    [CmdletBinding()]
	param(
		[Parameter(Mandatory = $false,
				   ValueFromPipeline = $true,
				   ValueFromPipelineByPropertyName = $true)]
		[string]$Text = 'Are you sure?'
	)
    Show-UDModal -Content {
        New-UDTypography -Text $Text
    } -Footer {
        New-UDButton -Text "Yes" -OnClick {
            $Session:Result = $true
            Hide-UDModal
        } -Style @{"border-radius" = "4px"}

        New-UDButton -Text "No" -OnClick {
            $Session:Result = $false
            Hide-UDModal
        } -Style @{"border-radius" = "4px"}

    } -Persistent
    return $Session:Result
}

That almost worked but not quite.
First time I call New-UDConfirm it still get a null value back, then I click one of the buttons, and then next time I call the function, I get either true or false depending on what I clicked the first time. I can do this multiple times, clicking different things, but I always get the result from the last click.

I short, the result is one behind, with a null first time.
But I feel we are getting closer :slight_smile:

Ah. I think it’s because Show-UDModal isn’t blocking. Not quite the same look and feel but you can also do this.

        function New-UDConfirm {
            <#
            .SYNOPSIS
            Shows a confirm object in a modal, returns either true or false.
            
            .DESCRIPTION
            Shows a confirm object in a modal, returns either true or false.
            #>
            [CmdletBinding()]
            param(
                [Parameter(Mandatory = $false,
                        ValueFromPipeline = $true,
                        ValueFromPipelineByPropertyName = $true)]
                [string]$Text = 'Are you sure?'
            )
            
            $options = [System.Management.Automation.Host.ChoiceDescription[]] @("Yes", "No")
            [int]$defaultchoice = 1
            $opt = $host.UI.PromptForChoice($Text , "", $Options,$defaultchoice)
            switch($opt)
            {
                0 { $true}
                1 { $false}
            }
        }

This would be a great function for this module:

1 Like

This actually works, but you are right, it’s not as pretty as the modal.
Not to be a princess, but I would prefer a pretty solution with buttons instead of a dropdown menu :princess:

This will wait. :ring:

function New-UDConfirm {
            <#
            .SYNOPSIS
            Shows a confirm object in a modal, returns either true or false.
            
            .DESCRIPTION
            Shows a confirm object in a modal, returns either true or false.
            #>
            [CmdletBinding()]
            param(
                [Parameter(Mandatory = $false,
                    ValueFromPipeline = $true,
                    ValueFromPipelineByPropertyName = $true)]
                [string]$Text = 'Are you sure?'
            )
            $Session:Result = $null
            Show-UDModal -Content {
                New-UDTypography -Text $Text
            } -Footer {
                New-UDButton -Text "Yes" -OnClick {
                    $Session:Result = $true
                    Hide-UDModal
                } -Style @{"border-radius" = "4px" }

                New-UDButton -Text "No" -OnClick {
                    $Session:Result = $false
                    Hide-UDModal
                } -Style @{"border-radius" = "4px" }

            } -Persistent
            while($Session:Result -eq $null) {
                Start-Sleep -Milliseconds 100
            }
            return $Session:Result
        }
2 Likes

Fantastic!!
This works exactly as I could wish for, thanks for the help! :smiley:

With the session var, it doesn’t even need a return statement, I can just use the same variable in the script calling the module.

Do you think I should make a pull request for the dashboard-utils or did you already implement it? :slight_smile:

Hi,
New-UDConfirm does not work for me anymore,
Don’t know why (Version: 3.10.4)

When I click on yes or no it not responding, when I remove the while statement it works but always return the same resault.

              New-UDElement -Tag 'div' -Content {
         New-UDButton -Id 'rstbtn'-Text 'Restart Server' -Icon (New-UDIcon -Icon 'arrows-rotate' -Bounce) -OnClick {
             $ChkBoxVal = (Get-UDElement -Id servers).Value
             if ($ChkBoxVal -eq 'anav') {   
                if (New-UDConfirm) {
                 Show-UDToast -Message "True" -Duration 10000 
                 Restart-Servers -ServerList ("SERVER1","SERVER2")
                }
            }

         }
        }  -Id 'ResetServers'

You can try just using the built in PromptForChoice.

$title = 'Confirm'
$question = 'Do you want to continue?'
$choices = 'Yes', 'No'

$decision = $Host.UI.PromptForChoice($title, $question, $choices, 1)
if ($decision -eq 0) {
    Write-Host 'Your choice is Yes.'
}
else {
    Write-Host 'Your choice is No.'
}