How to add an Array of Json Objects to a Json Object?

Hi there,

how is it possible to add an array of Json objects to the main Json Object?

I managed to add a value array:

// Json object
TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject);

// Value array
TArray< TSharedPtr<FJsonValue> > ValueArray;

// Create two values and add them to the array
TSharedPtr<FJsonValue> Value1 = MakeShareable(new FJsonValueString("value1"));    
ValueArray.Add(Value1);    
TSharedPtr<FJsonValue> Value2 = MakeShareable(new FJsonValueString("value2"));    
ValueArray.Add(Value2);

// Add the array to the Json object
JsonObject->SetArrayField("array", ValueArray);

However I would like to have the array as JsonObjects. That basically the array would be declared as:

TArray< TSharedPtr  <FJsonObject> > ObjArray;

and I add to the main FJsonObject:

// create JsonObj array
TArray< TSharedPtr<FJsonObject> > ObjArray;

// create a Json object and add a string field
TSharedPtr<FJsonObject> JsonObj = MakeShareable(new FJsonObject);    
JsonObj ->SetStringField("Abc", "AbcValue");

// add the object to the array
ObjArray.Add(JsonObj);

// ***THIS does not work***
JsonObject->SetArrayField("array", ObjArray);

=====EDIT 1 =====

Compile error:

  • error C2664: ‘void FJsonObject::SetArrayField(const FString &,const TArray,FDefaultAllocator> &)’ : cannot convert argument 2 from ‘TArray,FDefaultAllocator>’ to 'const TArray,FDefaultAllocator> &'JsonObject->SetArrayField(“array”, ObjArray);

  • Reason: cannot convert from ‘TArray,FDefaultAllocator>’ to ‘const TArray,FDefaultAllocator>’

  • No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Thanks!

1 Like

I haven’t used JSon in UE so far and “doesn’t work” is a bit unspecific, but maybe you’re running into the same problem as this poster: How to const cast TArray of TSharedPtr - Programming & Scripting - Epic Developer Community Forums

// create Json values array

TArray< TSharedPtr<FJsonValue> > ObjArray;

// create a Json object and add a string field

TSharedPtr< FJsonObject > JsonObj = MakeShareable(new FJsonObject);

JsonObj->SetStringField(“Abc”, “AbcValue”);

// create a Json value object to hold your Json object

TSharedRef< FJsonValueObject > JsonValue = MakeShareable( new FJsonValueObject( JsonObj) );

// add the object to the array

ObjArray.Add(JsonValue);

// THIS should work

AnotherJsonObj->SetArrayField(“array”, ObjArray);

Modifications for your code to build in bold

5 Likes

Hi, thanks for the answer! You missed the brackets when declaring JsonObj as shared pointer. Could you edit that, it might help others:

TSharedPtr < FJsonObject > JsonObj

Actually the editor removes it, try adding it as Code sample then it appears.

Fixed some typos, thanks for letting me know

Glad it helped

I’m finding a problem implementing this, isnt it circular?

Reading backwards; you have JsonObj which has an ArrayField of ObjArray. ObjArray contains a pointer to JsonObj, which has a StringField of “Abc”, “AbcValue”.

I might just be really confused by trying to modify your answer into my own code, but when I try to serialise JsonObj the editor crashes once it reaches 2GB in size :wink:

I edited to avoid confusion.
But there is no problem with code as it was.
If you explain your problem we might be able to help you out

I know this post has been a while ago, but running into the same problem as the OP and the last couple of days digging in the googles hasn’t got me there either :frowning:

@hsarret 's response got me part of the way there, but can’t quite piece it together
(I’m on ue5.1)

I’m using HTTP to send graphql queries and need the output to be programatic and in JSON format.

I’m trying to output json in the following format

{ 
	"page_input":
		{
				"page_num": 1, 
				"page_size": 100, 
				"sort_order": "ASC",
				"filter_by_inputs": 
					[
						{ 
						      "field_name": "unit_state",
						      "values": ["error", "targeted"]
						  }
				]
    		}
    }
    

The following what what I have:

// This is the top level dict
TSharedPtr<FJsonObject> VariablesJsonObject = MakeShareable(new FJsonObject);

// This is the page input dict
TSharedPtr<FJsonObject> PageInputJsonObject = MakeShareable(new FJsonObject);

// Add the page_input dict to the variables dict
VariablesJsonObject->SetObjectField("page_input", PageInputJsonObject);

// Add the other fields to the page_input dict
PageInputJsonObject->SetNumberField("page_num", 1);
PageInputJsonObject->SetNumberField("page_size", 100);
PageInputJsonObject->SetStringField("sort_order", "ASC");

// create the filter_by_inputs dict which will needed to be "Added" to the filter_by_inputs Array
TSharedPtr<FJsonObject> FilterByInputsJsonObject = MakeShareable(new FJsonObject);

// Create the filter_by_inputs array
TArray<FJsonObject> FilterByInputsArray;

// Add field to filter_by_inputs dict
FilterByInputsJsonObject->SetStringField("field_name", "op_state");

// Add the dict to the array
FilterByInputsArray.Add(*FilterByInputsJsonObject);

// create the field_values array and add the values to it
TArray<TSharedPtr<FJsonValue>> FieldValuesArray;
FilterByInputsJsonObject->SetArrayField("values", FieldValuesArray );
FieldValuesArray.Add(MakeShareable(new FJsonValueString("error")));
FieldValuesArray.Add(MakeShareable(new FJsonValueString("targeted")));

// Create the json value object to store the dict in
TSharedRef<FJsonValueObject> FilterByInputsJsonValueObject = MakeShareable (new FJsonValueObject(FilterByInputsJsonObject));

// Add the value object that is an array into the page_inputs dict
PageInputJsonObject->SetArrayField("filter_by_inputs", FilterByInputsJsonValueObject);

The error from the IDE (rider) I get, is
cannot convert TSharedRef<FJsonValueObect> to TArray<TSharedPtr<FJsonValue>>

my brain is melting lol. Any help would be greatly appreciated

What would be even more amazing, if there was a generator you could pass a json dict to and it would generate the ue cpp for it haha. (I looked, couldn’t find one :frowning: )

cheers :slight_smile:

// Create the filter_by_inputs array
TArray<TSharedPtr<FJsonValue>> FilterByInputsArray;
{
	TSharedPtr<FJsonObject> Item = MakeShareable(new FJsonObject);
	FilterByInputsArray.Add(MakeShareable(new FJsonValueObject(Item)));

	Item->SetStringField("field_name", "op_state");

	TArray<TSharedPtr<FJsonValue>> ValuesArray;
	ValuesArray.Add(MakeShareable(new FJsonValueString("error")));
	ValuesArray.Add(MakeShareable(new FJsonValueString("targeted")));

	Item->SetArrayField("values", ValuesArray);
}

// Add the value object that is an array into the page_inputs dict
PageInputJsonObject->SetArrayField("filter_by_inputs", FilterByInputsArray);
2 Likes

Thank you @Chatouille ! That got it for me.

I need to dig into what the { } are actually doing. It’s not clicking what that encapsulation is linked to.

Thank you again!

Doesn’t do anything, it’s just putting variables into a scope. I generally use this whenever I declare generic variables that are temporary, eg. store them in array and forget them. This way I don’t run into conflicts later on if I want to use that variable name again. Makes it simpler if you want to add a second item to the array for example.

1 Like