neoluu
neoluu

Reputation: 39

The property 'X' cannot be found on this object. Verify that the property exists

I have below function snippet within a script that throws error The property 'timeoffs' cannot be found on this object. I verified that the property exists.

function GetoffTime($startDate, $endDate, $teamUsers) {
    foreach ($user in $teamUsers){
      $body = @{
      "users" = @($user)
      } | ConvertTo-Json -compress
      
      $response = Invoke-WebRequest -Uri $URL -Method POST -Headers $headers -ContentType "application/json" -Body $body
      if ($response.StatusCode -eq "200") {
        $data = ConvertFrom-Json $response
        
        foreach($element in $data){
            #It would throw the property not found error at if statement below
            if($element.items.timeoffs.start.date){
            $timeoff += @{
              username = $element.items.username
              date = $element.items.timeoffs.start.date | Sort-Object
            }
    }
  }
  catch {
      Log-msg
  }
  return $timeoff
}

If I manually execute $response = Invoke-WebRequest -Uri $URL -Method POST -Headers $headers -ContentType "application/json" -Body $body in PS and convertfrom-json (like in function), the "timeoffs" property does exist as shown below. But when executed in function, im unable to access the property.

[![enter image description here][1]][1]

I've read that I should be prefixing like [Object]$data but had no luck. I'm probably mistaking something and would appreciate advice.

to add, executing the gettimeoff function in the shell works and does not error with property not found as shown below [![enter image description here][2]][2]

Interactive mode, i set stricmode to 2.0 and was able to reproduce error in shell. Here is an example of json where timeoffs is null. Would you know how I can skip ones that are null?

PS C:\Users\> $data

items
-----
{@{username=user; [email protected]; timeoffs=System.Object[]}}


PS C:\Users\> $data.items

username email                   timeoffs
-------- -----                   --------
user     [email protected]         {}

Adding logging of json to the console.

PS C:\Users\> GetTimeoffData $startDate $endDate $teamUsers
1727004858.89624 INFO Fetching timeoff data from Google Calendar
https://myapi.com/v1/timeoffs/?timeMin=2024-08-01&timeMax=2024-09-30

user1
user = 'user1'
json = '{"items":[{"username":"user1","email":"user1@search","timeoffs":[]}]}'
user2
user = 'user2'
json = '{"items":[{"username":"user2","email":"user2@search","timeoffs":[]}]}'
user3
user = 'user3'
json = '{"items":[{"username":"user3","email":"user3@search","timeoffs":[{"start":{"date":"2024-08-27","dateTime":null,"timeZone":null},"end":{"date":"2024-08-29","dateTime":null,"timeZone":null}},{"start":{"date":"2024-08-26","dateTime":null,"timeZone":n
ull},"end":{"date":"2024-08-27","dateTime":null,"timeZone":null}}]}]}'
user4
user = 'user4'
json = '{"items":[{"username":"user4","email":"user4@search","timeoffs":[{"start":{"date":"2024-08-01","dateTime":null,"timeZone":null},"end":{"date":"2024-08-03","dateTime":null,"timeZone":null}},{"start":{"date":"2024-08-05","dateTime":null,"timeZone":n
ull},"end":{"date":"2024-08-09","dateTime":null,"timeZone":null}},{"start":{"date":"2024-08-16","dateTime":null,"timeZone":null},"end":{"date":"2024-08-17","dateTime":null,"timeZone":null}},{"start":{"date":"2024-09-03","dateTime":null,"timeZone":null},"end":{"date":"202
4-09-04","dateTime":null,"timeZone":null}},{"start":{"date":"2024-09-04","dateTime":null,"timeZone":null},"end":{"date":"2024-09-05","dateTime":null,"timeZone":null}}]}]}'
user5
user = 'user5'
json = '{"items":[{"username":"user5","email":"user5@search","timeoffs":[{"start":{"date":"2024-08-26","dateTime":null,"timeZone":null},"end":{"date":"2024-08-31","dateTime":null,"timeZone":null}},{"start":{"date":"2024-09-20","dateTime":null,"timeZ
one":null},"end":{"date":"2024-09-21","dateTime":null,"timeZone":null}}]}]}'
user6
user = 'user6'
json = '{"items":[{"username":"user6","email":"user6@search","timeoffs":[{"start":{"date":"2024-08-21","dateTime":null,"timeZone":null},"end":{"date":"2024-08-24","dateTime":null,"timeZone":null}}]}]}'
user7
user = 'user7'
json = '{"items":[{"username":"user7","email":"user7@search","timeoffs":[{"start":{"date":"2024-09-09","dateTime":null,"timeZone":null},"end":{"date":"2024-09-14","dateTime":null,"timeZone":null}},{"start":{"date":"2024-09-06","dateTime":null,"timeZon
e":null},"end":{"date":"2024-09-07","dateTime":null,"timeZone":null}},{"start":{"date":"2024-08-12","dateTime":null,"timeZone":null},"end":{"date":"2024-08-13","dateTime":null,"timeZone":null}},{"start":{"date":"2024-08-08","dateTime":null,"timeZone":null},"end":{"date":
"2024-08-09","dateTime":null,"timeZone":null}},{"start":{"date":"2024-09-05","dateTime":null,"timeZone":null},"end":{"date":"2024-09-06","dateTime":null,"timeZone":null}},{"start":{"date":"2024-09-16","dateTime":null,"timeZone":null},"end":{"date":"2024-09-17","dateTime"
:null,"timeZone":null}},{"start":{"date":"2024-09-17","dateTime":null,"timeZone":null},"end":{"date":"2024-09-18","dateTime":null,"timeZone":null}}]}]}'
user8
user = 'user8'
json = '{"items":[{"username":"user8","email":"user8@search","timeoffs":[{"start":{"date":"2024-08-16","dateTime":null,"timeZone":null},"end":{"date":"2024-08-17","dateTime":null,"timeZone":null}},{"start":{"date":"2024-09-09","dateTime":null,"timeZone":n
ull},"end":{"date":"2024-09-11","dateTime":null,"timeZone":null}}]}]}'
user9
user = 'user9'
json = '{"items":[{"username":"user9","email":"user9@search","timeoffs":[{"start":{"date":"2024-08-12","dateTime":null,"timeZone":null},"end":{"date":"2024-08-13","dateTime":null,"timeZone":null}},{"start":{"date":"2024-08-13","dateTime":null,"timeZone":n
ull},"end":{"date":"2024-08-17","dateTime":null,"timeZone":null}}]}]}'
-- System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.Dict
ionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collect
ions.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry System.Collections.DictionaryEntry Syste
m.Collections.DictionaryEntry

Name                           Value
----                           -----
date                           {2024-08-26, 2024-08-27}
username                       user3
date                           {2024-08-01, 2024-08-05, 2024-08-16, 2024-09-03...}
username                       user4
username                       user5
date                           2024-08-21
username                       user6
username                       user7
date                           {2024-08-16, 2024-09-09}
username                       user8
date                           {2024-08-12, 2024-08-13}
username                       user9

Upvotes: 0

Views: 385

Answers (1)

mklement0
mklement0

Reputation: 439822

Your error implies that Set-StrictMode -Version 2 or higher is in effect in your script file, which reports an error whenever you try to access a non-existent property on an object.

By contrast, with strict mode -Off (the default) or at -Version 1, accessing a non-existent property quietly evaluates to $null, which is what you saw in your interactive session.

Since you want to keep strict mode at version 2 (or higher) in your script, you need to explicitly handle attempts to access non-existent properties.

Choose one of the following options:

  • Use a try ... catch statement to ignore the error:

    # Stores $null in $startDate if the property doesn't exist.
    $startDates = try { $element.items.timeoffs.start.date } catch { }
    if ($startDates) { 
      # property exists and is non-empty, work with it.
      #  ...
    }
    
  • Temporarily deactivate the script mode specifically around the property access you to know situationally fail, which you can do with the help of a child scope:

    # Stores $null in $startDate if the property doesn't exist.
    $startDates = 
      & {
        Set-StrictMode -Off # Takes effect only inside this { ... } block.
        $element.items.timeoffs.start.date
      }
    
  • In your specific scenario, check if $element.items.timeoffs is a non-empty array and access .start.date on it (via member-access enumeration) only if so (this assumes that all array elements are objects that have a .start property containing a nested object with a .date property):

    if ($element.items.timeoffs.Count -gt 0) { 
      # property exists and is non-empty, work with it.
      #  ...
    }
    

Upvotes: 1

Related Questions