cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - You can change your system assigned username to something more personal in your community settings. X

Working with JSON and Arrays

jensc
17-Peridot

Working with JSON and Arrays

Hello,

 

I've been working with JSON as inputs to services a lot more lately and I've noticed a strange behavior, at least for me. 

 

When I have set the Inputs as a JSON:

jensc_0-1667577638984.png

 

And put a JSON object with an array in it (with several objects in it), something like this:

jensc_1-1667577683248.png

When using this object in the code and trying to push some new objects into this array I get the error saying that the .push() function doesn't exist.

 

"TypeError: Cannot find function push in object"

 

But if I declare the exact same object in the code, something like this:

 

let array = {
    "PlatformData": [
        {
            "Comment": "User Projects (not the PTC projects)",
            "Description": "1\nP",
            "Instance": "",
            "ServerName": "",
            "TypeOfEntity": "Projects",
            "Timestamp": "2022-11-04 15:52:37.170",
            "Name": ""
        },
        {
            "Comment": "User Projects (not the PTC projects)",
            "Description": "",
            "Instance": "",
            "ServerName": "",
            "TypeOfEntity": "Projects",
            "Timestamp": "2022-11-04 15:52:37.170",
            "Name": ""
        }
    ]
};

let newObject = {
            "Comment": "User Projects (not the PTC projects)",
            "Description": "",
            "Instance": "",
            "ServerName": "",
            "TypeOfEntity": "Projects",
            "Timestamp": "2022-11-04 15:52:37.170",
            "Name": ""
        };

// local variable which works:
array.PlatformData.push(newObject);
// Service variable which doesn't work:
Input.PlatformData.push(newObject);

It is entirely possible that I just don't know enough about these different types. But to me it doesn't make much sense why one works while the other doesnt.

 

Any help with this would be much appreciated.

 

Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions

The issue is that you assume that the constructor used to package the input parameter as JSON is the same as the constructor used in code to build your object.

When you pass a JSON parameter between services (and this is what happens when you provide the default value for your input parameter) results in an internal object type of JSONObject. Here's a link to this object's JAVADOC to see its implementation, and here's the respective JSONArray type documentation. You will note that in there there's no push method, while it has instead a put equivalent.

This would work well:

inputParameter.PlatformData.put( {
            "Comment": "myuser",
            "Description": "3",
            "Instance": "",
            "ServerName": "",
            "TypeOfEntity": "",
            "Timestamp": "",
            "Name": ""
        });

 

Opposite, when you declare your object directly in Javascript, this results in a pure Javascript object (no Java JSONObject "wrapper") which has access directly to any method you'd expect in Javascript syntax.

 

 

View solution in original post

5 REPLIES 5
VladimirN
24-Ruby II
(To:jensc)

Article - "Error when pushing to JSON in ThingWorx Service": https://www.ptc.com/en/support/article/CS284117

jensc
17-Peridot
(To:VladimirN)

Hello, thank you for your answer.

 

I understand that it is not possible to use .push() on an object.

However if you look closely on the Input parameter, which is a JSON type, it includes the exact same "PlatformData" array as the variable in the code.

 

Maybe I named the variable a little bit badly in my first post. I will change it.

 

Here is maybe a better way to describe it:

 

 

let localJSON = {
    "PlatformData": [
        {
            "Comment": "User Projects (not the PTC projects)",
            "Description": "1\nP",
            "Instance": "",
            "ServerName": "",
            "TypeOfEntity": "Projects",
            "Timestamp": "2022-11-04 15:52:37.170",
            "Name": ""
        },
        {
            "Comment": "User Projects (not the PTC projects)",
            "Description": "",
            "Instance": "",
            "ServerName": "",
            "TypeOfEntity": "Projects",
            "Timestamp": "2022-11-04 15:52:37.170",
            "Name": ""
        }
    ]
};

let newObject = {
            "Comment": "User Projects (not the PTC projects)",
            "Description": "",
            "Instance": "",
            "ServerName": "",
            "TypeOfEntity": "Projects",
            "Timestamp": "2022-11-04 15:52:37.170",
            "Name": ""
        };

// local variable which works:
localJSON.PlatformData.push(newObject);
// Service variable which doesn't work:
Input.PlatformData.push(newObject);

 

 

To me "Input" and "localJSON" should be the exact same type, both JSON objects with an array called "PlatformData".

But it is only possibly to use .push() on one of the arrays, on the one variable declared in the code.

 

Hope this clears some things up.

 

Thanks,

nmilleson
17-Peridot
(To:jensc)

I'm not sure if this helps, but I've run into similar issues with JSON arrays in ThingWorx.  I'll use the Array.from() method to ensure that I get an array that I push to:

 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

The issue is that you assume that the constructor used to package the input parameter as JSON is the same as the constructor used in code to build your object.

When you pass a JSON parameter between services (and this is what happens when you provide the default value for your input parameter) results in an internal object type of JSONObject. Here's a link to this object's JAVADOC to see its implementation, and here's the respective JSONArray type documentation. You will note that in there there's no push method, while it has instead a put equivalent.

This would work well:

inputParameter.PlatformData.put( {
            "Comment": "myuser",
            "Description": "3",
            "Instance": "",
            "ServerName": "",
            "TypeOfEntity": "",
            "Timestamp": "",
            "Name": ""
        });

 

Opposite, when you declare your object directly in Javascript, this results in a pure Javascript object (no Java JSONObject "wrapper") which has access directly to any method you'd expect in Javascript syntax.

 

 

Hello,

 

This worked great!

I was not aware of this JSONObject wrapper but now that you point it out it makes sense.

 

Thank you!

Top Tags