Null error while parsing JSON file in Flutter

474 Views Asked by At

Im trying to create an app that reads a JSON file and displays its content.

The JSON File is as follows:

    "Jett": {
        "name":
            "Jett",
        "info":
            "From Korea comes Jett, an agile fighter who prioritizes movement over everything. Her abilities include a teleportation-based dash and an updraft that lets her reach higher ledges. She also has a smokebomb ability to hinder sightlines and a powerful Bladestorm ultimate that deals moderate-to-heavy damage and remains accurate even while she's moving [1]. Jett is one of the few Agents with a passive ability. Holding the jump key while in the air will allow Jett to slow her descent. Jett's Ultimate allows her to wield several throwing knives that deal moderate damage and kill on headshots. Getting a kill replenishes your daggers and you can choose to throw them one at a time or throw all remaining daggers in a short-ranged burst.",
        "ability 1":{
            "name" : "Cloudburst",
            "type" : "Basic",
            "cost" : "100",
            "duration" : "7 Secs",
            "health" : "N/A",
            "description" : "Instantly throw a projectile that expands into a brief vision cloud on impact with a surface. Hold the ability key to curve the cloud in the direction of your crosshair."
        },

        "ability 2" : {
            "name" : "Updraft",
            "type" : "Basic",
            "cost" : "100",
            "duration" : "N/A",
            "health" :"N/A",
            "description" : "Instantly propel Jett high into the air."
        },

        "ability 3" : {
            "name" : "Tailwind",
            "type" : "Signature",
            "cost" : "None",
            "duration" : "N/A",
            "health" :"N/A",
            "description" : "Instantly propel in the direction she is moving. If Jett is standing still, she will propel forward."
        },
        
        "ability 4" : {
            "name" : "Bladestorm",
            "type" : "Ultimate",
            "cost" : "6 Ult Points",
            "duration" : "N/A",
            "health" :"N/A",
            "description" : "Equip a set of 5 highly accurate throwing knives. Fire to throw a single knife. Alternative Fire to throw all remaining daggers at once. Restocks upon killing an enemy."
        }
        

    },

    "Breach": {
        "name": "Breach",
        "info":
            "Breach fires powerful, targeted kinetic blasts to aggressively clear a path through enemy ground. The damage and disruption he inflicts ensures no fight is ever fair. Breach's main gimmick is the ability to use all of his abilities through the geometry of the map,whether it is through walls, roofs, or terrain. This ability set rewards experienced players for knowing the maps well. His abilities also seem to reward an aggressive playstyle despite most of his abilities being crowd-control based.",
        "ability 1":{
            "name" : "Aftershock",
            "type" : "Basic",
            "cost" : "100",
            "duration" : "N/A",
            "health" : "N/A",
            "description" : "Equip a fusion charge. Fire the charge to set a slow-acting burst through the wall. The burst does heavy damage to anyone caught in its area."
        },

        "ability 2" : {
            "name" : "Flashpoint",
            "type" : "Basic",
            "cost" : "200",
            "duration" : "2 Secs",
            "health" :"N/A",
            "description" : " Equip a blinding charge. Fire the charge to set a fast-acting burst through the wall. The charge detonates to blind all players looking at it."
        },

        "ability 3" : {
            "name" : "Fault Line",
            "type" : "Signature",
            "cost" : "None",
            "duration" : "N/A",
            "health" :"N/A",
            "description" : "Equip a seismic blast. Hold Fire to increase the distance. Release to set off the quake, dazing all players in its zone and in a line up to the zone."
        },
        
        "ability 4" : {
            "name" : "Rolling Thunder",
            "type" : "Ultimate",
            "cost" : "7 Ult Points",
            "duration" : "N/A",
            "health" :"N/A",
            "description" : "Equip a seismic charge. Fire to send a cascading quake through all terrain in a large cone. The quake dazes and knocks up anyone caught in it."
        }
        
}

A class holds the a String named 'characterName' which is passed to another class named CharacterPageConstructor using the following code:

onTap: () {
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => CharacterPageConstructor(characterName)));
      },

The CharacterPageConstructor takes this characterName as a parameter to search for the name in the Json file. The code I used to read it is as follows:

class CharacterPageConstructor extends StatelessWidget {
  final String characterName;
  CharacterPageConstructor(this.characterName);
  String jsonData;
  Future<String> _read() async {
    try {
      final File file = File('assets/data/character_data.json');
      jsonData = await file.readAsString();
    } catch (e) {
      print("Couldn't read file");
    }
    return jsonData;
  }

  Widget build(BuildContext context) {
    Map<String, dynamic> characterData = jsonDecode(jsonData);
    var name = characterData[characterName]['name'];
    var info = characterData[characterName]['info'];
    return Scaffold(
      backgroundColor: Color.fromARGB(255, 15, 23, 34),
      body: Container(
              margin: EdgeInsets.all(20),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(5.0),
                color: Color.fromARGB(175, 252, 70, 82),
              ),
              child: Row(
                children: [ Text(name),
                            Text(info)                       

However, in the end I get the following error:

The following NoSuchMethodError was thrown building CharacterPageConstructor(dirty):
The getter 'length' was called on null.
Receiver: null
Tried calling: length

The relevant error-causing widget was
CharacterPageConstructor
lib\characterBox.dart:40

When the exception was thrown, this was the stack
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1      _parseJson (dart:convert-patch/convert_patch.dart:39:28)
#2      JsonDecoder.convert (dart:convert/json.dart:505:36)
#3      JsonCodec.decode (dart:convert/json.dart:156:41)
#4      jsonDecode (dart:convert/json.dart:96:10)
...

Please note that the error lib\characterBox.dart:40 refers to the following line:

builder: (context) => CharacterPageConstructor(characterName)));
2

There are 2 best solutions below

3
On BEST ANSWER
final File file = File('assets/data/character_data.json');

jsonData = await file.readAsString();

Change to:

String data = await rootBundle.loadString('assets/data/character_data.json');

jsonData = json.decode(data);

print(jsonData);

or

final file = File('assets/data/character_data.json');

String data = await file.readAsString();

jsonData = json.decode(data);

print(jsonData);
0
On

You have to convert JSON string to JSON object

eg

var jsonData = json.decode(string);