0
votes

I'm calling the VSTS Pull Request Query documented here: https://docs.microsoft.com/en-us/rest/api/vsts/git/pull%20request%20query/get?view=vsts-rest-4.1

It returns an object array of results. I wanted to detect when no results are returned and react accordingly. I thought I could check the response.results.length, but it will be 1 even if there are no results. It returns an array of 1 empty object. I'm having a hard time detecting that condition. The one solution I thought of is:

    if(($pullRequests.results | Get-Member -MemberType Properties).Length -eq 0){some code}

Since a vanilla ps object has 4 members and the populated object has an additional note property it will work. My method seems hackish, is there a better approach?

I tried checking length, exists, and bool:


    PS> $pullRequests.results[0].Length
    1
    PS> $temp = $pullRequests.results[0]
    PS> $temp | Get-Member

    TypeName: System.Management.Automation.PSCustomObject

    Name        MemberType Definition
    ----        ---------- ----------
    Equals      Method     bool Equals(System.Object obj)
    GetHashCode Method     int GetHashCode()
    GetType     Method     type GetType()
    ToString    Method     string ToString()

    PS> $temp -eq $null
    False
    PS> if($temp){"YAY"}else{"BOO"}
    YAY

2
That actually sounds like a bug in the API -- an empty array is not an empty object. How are you getting $pullRequests -- with Invoke-RestMethod? Try Invoke-WebRequest to see what it's actually returning and whether that can be massaged before passing it to ConvertFrom-Json. (That also suggest the reverse should be possible -- checking for ($pullRequests.results[0] | ConvertTo-Json -Compress) -eq "{}". Though that's still a bit hackish and inefficient.) - Jeroen Mostert
If I use webRequest the response content contains: "results":[{}] - Justin Holbrook
The response an array of one "unpoplated" object - Justin Holbrook
Then I would check if the response you're getting is [{}] and | ConvertFrom-Json otherwise. - Ansgar Wiechers
Per the docs, "each entry in the list is a dictionary of commit->pull requests." So technically, if you supply it one query it's correct to return one empty dictionary. If multiple queries were supplied, each of these could be empty. To see if an individual result is not empty, the cleanest way is probably if ($result | Get-Member -Type Properties). - Jeroen Mostert

2 Answers

1
votes

This does sound like a bug in the API. As a work around, checking for properties (as opposed to members which also includes methods) seems like the right approach. The easiest way to do this ix as follows:

if ($pullRequests.PSObject.Properties)
{
    "Object has properties so process it."
}
else
{
    "Object has no properties, ignore it."
}
0
votes

Oh man, that stinks.

Lemme make sure I understand your problem. You're expecting an object that looks something like the following when data is returned:

$full_collection_ps_objects = `
    @([PSCustomObject]@{a=1;b=2}, [PSCustomObject]@{a=1;b=3})

A collection of psobjects.

When no data is returned, you get an array of objects with a single empty psobject:

$empty_collection_ps_objects = @([PSCustomObject]@{})

I think you nailed it. Property count is a good indicator. I'm a little neurotic. That might lead me to get paranoid that another default property might appear at some later point. I might consider looking for specific field name, a primary key of sorts with something like:

if( $($empty_collection_ps_objects | Get-Member).Name -contains 'a' ) { $true }
if( $($full_collection_ps_objects | Get-Member).Name -contains 'a' ) { $true }