1

I have stumbeled accross an error that cought me totally by surprise, so I wanted to check with you if this makes sense...

Item := Songs.Items[Index] as TJSONObject;
ThisTrack := Item.Values['track'] as TJSONObject;
if (Assigned(ThisTrack)) then Begin;

End; 

Songs is a TJSONArray, Item and ThisTrack are TJSONObject.

If Item does not contain a "track", the above code throws an ERangeError exception on the 2nd line.

This is the first time I'm seeing this, and I am VERY sure, I had "NIL AS <something>" a lot in the past.

Is this a JSON-class specific issue?

Is the workaround for this really as follows?

ThisTrack: TJSONValue;

Item := Songs.Items[Index] as TJSONObject;
ThisTrack := Item.Values['track'];
If Assigned(ThisTrack) then Begin;
  Tracks := (ThisTrack as TJSONObject).Values['uri'].Value);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Wolfgang Bures
  • 509
  • 4
  • 12
  • The problem was that the `track` value was there, but had the value null. My previous JSON object returned NULL for the value in that case, now I need to check for `ThisTrack.null`! – Wolfgang Bures Oct 29 '20 at 17:50

1 Answers1

0

The TJSONObject.Values[] property returns a nil pointer if the requested child is not found.

The as operator does not raise an exception if given a nil pointer, it will return a nil pointer. So whether you cast or not, you still need to check for nil before accessing an object that may or may not exist.

Regarding the ERangeError exception, you can't get that error on the Item.Values['track'] as TJSONObject expression, as you indicated. But you could get it from the Songs.Items[Index] expression, if Index is out of bounds.

Also, you have an erroneous ; after Begin, you need to remove that.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770