Count is not a function on TJSONArray

I have an object that contains a TJSONArray. However, when I try to access the Count method I get:

ERROR
Uncaught TypeError: this.FProducts.GetCount$1 is not a function | 
TypeError: this.FProducts.GetCount$1 is not a function

Examining the object in debug mode shows that it is created and populated.

Any ideas?

Use TJSArray and try Length instead Count

var inputdata:TJSArray;
begin
inputdata.Length
end;

This is very strange. Count is a property of TJSONArray (declared in WEBLib.JSON.pas) and GetCount a function.
Are you 100% sure that at the moment of access, FProducts is effectively an instance of the type TJSONArray?

It looks like.

The object is

TSMXUtilsSvc = Class
  Private
    FClient: TXDataWebClient;
    FProducts: TJSONArray;
  Protected
  Public
    Constructor Create; Reintroduce;
    Destructor Destroy; Override;
    Function ProductList: TJSONArray;
    Procedure LoadProducts;
    Function ProductName(Const Id: Integer): String;
  End;

and the loadings is done

procedure TSMXUtilsSvc.LoadProducts;
  Procedure OnSuccess(Response: TXDataClientResponse);
  Begin
    FProducts := TJSONArray(Response.Result);
  End;

  Procedure OnError(Error: TXDataClientError);
  Begin
    //AOnError(Format('%s: %s', [Error.ErrorCode, Error.ErrorMessage]));
  End;

Begin
  if Assigned(FProducts) then
  begin
    FProducts.Free;
    FProducts := Nil;
  end;

  FClient.RawInvoke('ISMXUtilsService.ProductList', [], @OnSuccess, @OnError);

end;

The issue is in

function TSMXUtilsSvc.ProductName(const Id: Integer): String;
var I: Integer;
    lProduct: TJSONObject;
begin
  Result := 'unknown product';
  for I := 0 to FProducts.Count - 1  do
  begin
    lProduct := FProducts[I] as TJSONObject;
    if lProduct.GetJSONValue('Id').ToInteger = Id then
    begin
      Result := lProduct.GetJSONValue('Name');
      Exit;
    end;
  end;
end;

Looking at FProducts at that point in the debugger shows:

Array(4)
0: {2: "GiftAider Small"}
1: {3: "GiftAider Standard"}
2: {4: "GiftAider Agent"}
3: {5: "VAT Submitter"}
length: 4
__proto__: Array(0)

I don't think you can just cast an XData response to a TJSONArray.
Did you check if EFFECTIVELY is one?
TJSONArray(Response.Result);

Please consider @Czech_Tomasz contribution above. It's the correct answer. TJSONArray is not TJSArray.

Just to confirm switching to TJSArray as suggested by @Czech_Tomasz did the trick. I just thought that as the XData Server returned a TJSONArray taht's what should be used on the client side.

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.