1

i'm trying to read stringfrom json file and pass it to my UI Text in Unity, The issue i'm facing is that the string is always null and i'm not sure why, Right now i find the JSON file path and read it, but when i try to access the string it's null. i'm not sure how to read the json. I really don't understand how this all works. i'm new to JSON format and i'm trying to practice it. This is my first approach. i'm using Unity Engine, and i'm reading the json file using Streaming Assets

Read Data from Json Script:

using UnityEngine;
using System.IO;


public class ReadFromJson : MonoBehaviour {

private string _filePath = "myText.json";

Data dh;

string str;
 void Start()
{



    LoadGameData();
}

public Data getCurrentRoundData()
{
    return dh;
}

private void LoadGameData()
{
    string filePath = Path.Combine(Application.streamingAssetsPath, _filePath);


    if (File.Exists(filePath))
    {

        string dataAsJSON = File.ReadAllText(filePath);
        DataHolder loadedData = JsonUtility.FromJson<DataHolder>(dataAsJSON);

        dh = loadedData.data;
        str = loadedData.data.TextToPass;
        Debug.Log("My Text is" + dh.TextToPass);

        Debug.Log("Path Exist");

    }


    else
    {
        Debug.LogError("CANNOT LOAD GAME DATA!!");
    }

}

}

Manager that applies the json data to my UI Text

    DataController = FindObjectOfType<ReadFromJson>();

    _data = DataController.getCurrentRoundData();


    myText.text = _data.TextToPass;

DataHolder.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]

public class DataHolder {

public Data data;

}

Json Text

{"DataHolder":

    {
        "TextToPass":"I'm A Horse"
    }

}

Data.cs

[System.Serializable]
public class Data {

public string TextToPass ;
}

What i get is TextToPass is null

Nanopl
  • 77
  • 1
  • 13
  • Can you share your DataHolder model? – mindOfAi Apr 03 '17 at 07:21
  • Yes Check update question – Nanopl Apr 03 '17 at 07:22
  • 2
    Your question is lacking so many things. You need to post the json file you are reading. Does the `File.Exists` return true? What is `TextToPass`? You can see how to read json in Unity [here](https://stackoverflow.com/questions/36239705/serialize-and-deserialize-json-and-json-array-in-unity/36244111#36244111). It looks like you want to save GameData with Json. I made a helper class for that [here](http://stackoverflow.com/a/40966346/3785314). – Programmer Apr 03 '17 at 07:22
  • How about the Data model? – mindOfAi Apr 03 '17 at 07:23
  • File Exist returns true yes, and my json just has a TextToPass that says Im a horse, i simply want to read that text and apply it to my Ui text – Nanopl Apr 03 '17 at 07:24
  • And your `Data` class? – Programmer Apr 03 '17 at 07:26
  • The json doesn't match the class structure. `DataHolder->Data->TextToPass` (I'm guessing). Your JSON says `DataHolder->TextToPass` – Fredrik Schön Apr 03 '17 at 07:28
  • Here is my advice to you. Don't try to create json data by hand if you already have a class. Simply create new `DataHolder` instance, populate it then generate the json by calling `JsonUtility.ToJson`. Save that to file. That's it. – Programmer Apr 03 '17 at 07:33
  • i dont get =/ I need to save files now? I just need to read from the JSON – Nanopl Apr 03 '17 at 07:45

2 Answers2

1

The model has Data, the JSON has DataHolder. The JSON library doesn't assume that "oh, there's one property, they must have meant that" - it goes by name, and the names don't match.

Either change your types, or change the JSON. They need to match. As an illustration, a type of the form:

public class Foo {
    public int Bar {get;set;}
}

matches JSON of the form:

{ "Bar": 123 }
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Will this work with Unity? I think there's an issue with their properties. – mindOfAi Apr 03 '17 at 07:37
  • I really.. dont get it.. I dont see my issue exactly. What type need to be changed – Nanopl Apr 03 '17 at 07:39
  • @Nanopl your root type is DataHolder; it only has a Data property. The json specified a DataHolder property - which **does not exist** in DataHolder. The json should be "data", or the type needs changing. Your json would be the equivalent of `{ "Foo": ... }` re my example – Marc Gravell Apr 03 '17 at 08:08
  • @Nanopl pro tip: when debugging deserialization issues, the easiest way to find the problem is to forget deserialization, and instead **serialize** what you have, and compare the output. – Marc Gravell Apr 03 '17 at 08:11
  • I changed my json file into the path DataHolder > Data > Text. But it still doesn't work. wasn't this the issue? – Nanopl Apr 03 '17 at 08:13
  • I really dont understand how this is all connected and working together. I removed the data holder and i updated my json to just Data > Text, and for this line now i just Pass the Data DataHolder loadedData = JsonUtility.FromJson(dataAsJSON); Im not even sure what this line does. i assume it reads from the json file. but how do i get the data i need from the json file and apply it to my UI text? like im trying to do just one simple thing. read 1 variable and apply it to text how simple is that and yet i failed in every way... – Nanopl Apr 03 '17 at 08:21
  • @Nanopl I didn't mention anything whatsoever about paths... k; let's take this back a step. This JSON should work: `{"data": { "TextToPass":"I'm A Horse" } }`. The *reason* it should work is that you're deserializing ``, and `DataHolder` has a `data` field, which is an object that in turn has a `TextToPass` field. However, your JSON isn't that; your json tries to deserialize ``, where the data is in a field/property called `"DataHolder"`... but: your `DataHolder` class ***doesn't have*** a field/property called `"DataHolder"`. It has one called `data`. – Marc Gravell Apr 03 '17 at 08:26
  • Why should dataHolder have a field called DataHolder. isn't it correct that it should have Data... How can this be done in another way. lets say from scratch.. How do i approach this.. – Nanopl Apr 03 '17 at 08:32
  • @Nanopl "Why should dataHolder have a field called DataHolder. isn't it correct that it should have Data.." - because the name in the json is "DataHolder", not "data". The two **need to match**. Note, however ,that `DataHolder` **cannot** declare a property called `DataHolder`, so if your json cannot change you either need to change the type name, or use configration to tell the serializer what name to use. This might mean via attributes, for example `[JsonProperty("DataHolder")]` for Json.NET – Marc Gravell Apr 03 '17 at 08:36
  • So i need to change my json file or change the dersilization? my issue is that i dont understand json flow and how it's working and im confused with data and data holder. i know they need to match but idk where is my issue? My matching it, im saying go to DataHolder then data and get my the text.. – Nanopl Apr 03 '17 at 08:40
  • @Nanopl "My matching it, im saying go to DataHolder then data and get my the text.." - no you're not; you might think that's what you're asking it to do, but it isn't. You're saying "fill this object that has a 'data' property" - there is no "DataHolder". The json library doesn't look at the type names, it only looks at the **member** names (by "members" here, I mean fields and properties). The only member name in the root object (in your C# class) is `data`. Not `DataHolder`. Thus, the JSON tool isn't interested in `"DataHolder": {...}` is the JSON, because there is **nowhere to put that**. – Marc Gravell Apr 03 '17 at 09:00
  • so how should the json be? with or Withoutdata holder? – Nanopl Apr 03 '17 at 09:53
  • @Nanopl to match your classes? I already said nearly 2 hours ago: `{"data": { "TextToPass":"I'm A Horse" } }` – Marc Gravell Apr 03 '17 at 10:20
  • Yes yes but should the json contain "DataHolder" : {"data" : {"Text,=..": im a housr }} or not without Dataholder? Because i tried it with both and both of them didn't work – Nanopl Apr 03 '17 at 10:26
  • @Nanopl what you've just posted isn't valid JSON. No, it shouldn't contain "DataHolder" because there is no **member** called `DataHolder`, and the serializer cares about the **member**; the member is "data". No, it shouldn't contain "Text", because there is no **member** called "Test" - it is "TextToPass". – Marc Gravell Apr 03 '17 at 10:32
  • Yes but i removed DataHolder and i tested it several times but it never worked – Nanopl Apr 03 '17 at 10:41
  • @Nanopl yet again, allow me to repeat: when having problems deserializing, **forget** about deserializing, and instead serialize; have a look at what comes *out*; that will tell you what the issue is – Marc Gravell Apr 03 '17 at 11:05
0

I'm not sure but this might solve your problem. Change your models to this:

Data model:

[System.Serializable]

public class Data {

public DataHolder dataHolder;

}

And your DataHolder model:

[System.Serializable]

public class DataHolder  {

public string TextToPass;

}

Hope it helps!

mindOfAi
  • 4,412
  • 2
  • 16
  • 27
  • Doesn't work, I changed it and i got errors, then i fixed them it's basically just changing names.. – Nanopl Apr 03 '17 at 07:38