How to load an array with JsonUtility?

I have a json array like this:

[
    {
        "key": "here's the key",
    },
    {
        "key": "here's the key",
    }
]

I try to load like this:

[Serializable]
public class Info
{
    public string key;
}

var asset = Resources.Load<TextAsset>("JsonTest");
var info = JsonUtility.FromJson<Info[]>(asset.text);

But it says like this:

4 Likes

Did you make the json yourself?

yes

is asset null by any chance?

Nope :wink:

1 Like

try inheriting from System.Object

Nothing different. If I print .Lenght it says 174090232 :hushed:

change var asset=Resources.Load(“JsonTest”);
to
var asset=Resources.Load(“JsonTest.json”);

Hi,

We currently do not support array types for top-level JSON deserialization (like Info[ ]). You need to wrap the JSON in an object, like this:

{ "infos": [
   { "key" : "key 1" },
   { "key" : "key 2" }
] }

and then make a little wrapper class to match:

[Serializable]
public class InfosCollection
{
   public Info[] infos;
}

JsonUtility.FromJson<InfosCollection>(...);

We know that this is not ideal and it’s on the list to handle top-level arrays properly in the future.

29 Likes

Thanks for the instructions Richard, Can you give an example on how to retrieve value for individual key such that a row has more than one key and its respective values. ?

Ex :
{
“object”:
{
“name”: “nm”,
“place”: “plc”,
“description”: “dscrptn”,
},
{
“name”: “nm”,
“place”: “plc”,
“description”: “dscrptn”,
},
{
“name”: “nm”,
“place”: “plc”,
“description”: “dscrptn”,
},
etc
}
How to access each values or say in a loop or something like that ?

1 Like
[System.Serializable]
public struct MyObject
{
   [System.Serializable]
   public struct ArrayEntry
   {
      public string name;
      public string place;
      public string description;
   }

   public ArrayEntry[] object;
}
6 Likes

I made this helper method to wrap a json around a class, this way you don’t need to change code on the server for accommodating the json top-level array problem .

    public static string WrapToClass(this string source, string topClass){
        return string.Format("{{ \"{0}\": {1}}}", topClass, source);
    }
3 Likes

Took me a while to notice that FromJson doesn’t work if the class members are defined as properties

3 Likes

Correct; same as the Inspector.

I wrote a little workaround:

public class JsonHelper
{
    public static T[] getJsonArray<T>(string json)
    {
        string newJson = "{ \"array\": " + json + "}";
        Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>> (newJson);
        return wrapper.array;
    }

    [Serializable]
    private class Wrapper<T>
    {
        public T[] array;
    }
}

You can now simple deserialize like this:

YouObject[] objects = JsonHelper.getJsonArray<YouObject> (jsonString);

Very surprising a such basic feature is not implemented…

32 Likes

This worked beautifully! Thanks ffleurey

Hi, this helped a lot. Thank you!

Hi,
I’m trying this answer, but have doubts about how to properly set YouObject[ ]?
Thanks for the help

2 Likes

JSON Utility class doesn’t support Array types or List yet?

I’m trying something like this to use Lists and seems to work well, but i’m not sure if is a good implementation:

[System.Serializable]
public class PlayerStats{

public int life;
public string name;
public int energy;
}

Then,

[System.Serializable]
public class PlayerStatsList {

    public List <PlayerStats> playerStats;
}

Now, in the class that i wan’t to access to the JSON File:

public PlayerStatsList myPlayerStatsList = new PlayerStatsList();

JsonUtility.FromJsonOverwrite (jsonText, myPlayerStatsList);

With this, i have all the info loaded from the JSON file in the list myPlayerStatsList.playerStats.

The JSON File must have the same structure that the PlayerStats class, like this:

{
    "PlayerStats": [
        {
            "life": "10",
            "name": "Kratos",
            "energy": 100
        },
        {
            "life": "80",
            "name": "Nathan",
            "energy": 20
        },
        {
            "life": "90",
            "name": "Link",
            "energy": 25
        }
    ]
}
6 Likes

Simple and clever, Thanks !