0

I'm calling the VSTS Pull Request Query documented here: https://learn.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

5
  • 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.) Commented Aug 22, 2018 at 13:29
  • If I use webRequest the response content contains: "results":[{}] Commented Aug 22, 2018 at 13:35
  • The response an array of one "unpoplated" object Commented Aug 22, 2018 at 13:36
  • Then I would check if the response you're getting is [{}] and | ConvertFrom-Json otherwise. Commented Aug 22, 2018 at 13:41
  • 1
    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). Commented Aug 22, 2018 at 13:47

2 Answers 2

1

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."
}
Sign up to request clarification or add additional context in comments.

3 Comments

Looks like this object has some default properties on it: PS>$pullRequests.results.PSObject.Properties | select name Name ---- Count Length LongLength Rank SyncRoot IsReadOnly IsFixedSize IsSynchronized
Reading the question, I think is should be $pullRequests.results[0].PSObject.Properties or $Temp.PSObject.Properties. The problem with this solution could be that if there is no .results at all, you will get a Cannot index into a null array error.
This is probably the closest to the answer I've settled on. I had to wrap the properties in an array: if (@($pullRequests.results[0].PSObject.Properties).Count -eq 0) {}
0

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 }

5 Comments

One challenge with this approach. The property that comes back is a guid which I won't know ahead of time.
The guid is the value or the column? You're getting the commit hash from VSTS. I would've thought that the commit hash would come back in a field named "commit" or something like that.
The column. Running this: "($pullRequests.results | get-member).Name" returns you: "Equals GetHashCode GetType ToString x7f98xxx40d5exxx0f4xxxe04xxx8c8xxxe19xxx"
I added some x's since we're a little crazy about any kind of indentifying data :)
Gotcha. No, I see your point then. This won't work for your use-case. I assumed the column names were static and known.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.