Issue while displaying "foreach" values

43 Views Asked by At

I have an powershell script which get's a list of customers from an json file, and then print it, based on what it typped until now. But, even the "list" block being after the "userInput header", it display the list before it, why?

json example:

[
  {
    "id": 123,
    "name": "Example LTDA",
    "database": "SqlServer"
  },
  {
    "id": 321,
    "name": "ECOMMERCE SA",
    "database": "Oracle"
  }
]

script:

$customersJson = Get-Content "%jsonpath%\customers.json" | ConvertFrom-Json | ForEach-Object { $_.name }

while ($true) {
    #Clear-Host
    [console]::CursorVisible = $false

    #Write-Host "DEBUG: `nfullString: $fullstring `nuserInput: $userInput `nFIM." -ForegroundColor Red
    Write-Host "Type the customer name:" -ForegroundColor Yellow
    Write-Host "> " -NoNewline
    Write-Host $fullstring -ForegroundColor Cyan
    $userInput = [System.Console]::ReadKey($true)

    if( $userInput.Key -eq "Backspace" )  { $fullstring = $fullString -replace “.$”      }
    elseif( $userInput.Key -eq "Enter" ) { return $fullstring                            }
    else                                { $fullstring = $fullString + $userInput.KeyChar }

    if(($fullstring.Length -gt 1) -and ($null -ne $fullstring)) {
        $customersList = $customersJson | Where-Object { $_ -match $fullstring } #| Select-Object -First 10

        Write-Host "____________________________`n" -ForegroundColor DarkGray
        foreach($customer in $customersList) {

            # Primeira letra maíúscula
            $customer = $customer.ToLower()
            $customer = $customer.Replace($customer[0],$customer[0].ToString().ToUpper())
            if ($fullstring -eq $customer) {
                Write-Host $customer -ForegroundColor DarkRed
            } else {
                Write-Host $customer -ForegroundColor DarkGray
            }
        }
        Write-Host "____________________________" -ForegroundColor DarkGray
    }

}

[console]::CursorVisible = $true

Write-Host "Typed customer: $fullString" -ForegroundColor Red

Display the customer list, after the prompt("Type the customer name") header, not before.

1

There are 1 best solutions below

2
Mathias R. Jessen On BEST ANSWER

If you want the prompt after the customer list, move the ReadKey statement until after you've rendered the list:

$customersJson = Get-Content '%jsonpath%\customers.json' | ConvertFrom-Json | ForEach-Object { $_.name }

$fullString = ''
[console]::CursorVisible = $false

while ($true) {
    Clear-Host

    # 1. Write prompt header
    Write-Host 'Type the customer name:' -ForegroundColor Yellow

    # 2. Optionally write customer list
    if ($fullstring.Length) {
        $customersList = $customersJson | Where-Object { $_ -match $fullstring } #| Select-Object -First 10

        Write-Host "____________________________`n" -ForegroundColor DarkGray
        foreach ($customer in $customersList) {

            # Primeira letra maíúscula
            $customer = $customer.ToLower()
            $customer = $customer.Replace($customer[0], $customer[0].ToString().ToUpper())
            if ($fullstring -eq $customer) {
                Write-Host $customer -ForegroundColor DarkRed
            }
            else {
                Write-Host $customer -ForegroundColor DarkGray
            }
        }
        Write-Host '____________________________' -ForegroundColor DarkGray
    }

    # 3. Prompt for next char
    Write-Host '> ' -NoNewline
    Write-Host $fullstring -ForegroundColor Cyan
    $userInput = [System.Console]::ReadKey($true)

    if ( $userInput.Key -eq 'Backspace' ) { 
        $fullstring = $fullString -replace '.$'      
    }
    elseif ( $userInput.Key -eq 'Enter' ) { 
        return $fullstring                            
    }
    else { 
        $fullstring = $fullString + $userInput.KeyChar 
    }
}

[console]::CursorVisible = $true

Write-Host "Typed customer: $fullString" -ForegroundColor Red