How to test if json property is present during the build of a Flutter ListView

2,821

You can use the null coalesce operator like so:

 new Text("Description: " + newData[index]['description'] ?? ''),

This will print the description if it exists, and an empty string if it doesn't.

Share:
2,821
dev_RGT
Author by

dev_RGT

Updated on December 11, 2022

Comments

  • dev_RGT
    dev_RGT over 1 year

    I'm beginner in Flutter and Dart.

    I have a local JSON file, read it and I want to display the JSON Data in the ListView. But in my JSON data I haven't always all the different properties. So when I want to display a text, the value of the property is no existing because the property is not existing (In the case is the Property "description".

    How could I solve it ?

    Thank you in advance for your help

    I tried ternary operator I tried with the function containsKey

    But maybe I did it wong ?

    ... json

    [
      {
        "createdBy": "bddae0de-320c-41a9-a69b-75793758b7a7",
        "description": "Fhjifgsdsdsd",
        "endDateTime": "1477490400000",
        "hasPicture": "false",
        "isActive": "true",
        "isAdminActive": "true",
        "maxParticipants": "50",
        "startDateTime": "1476799200000",
        "title": "Song Church Story Telling",
        "type": "Music"
      },
      {
        "createdBy": "-KHzgxS6KBqu1rNmJzpT",
        "endDateTime": "1476378000000",
        "hasPicture": "false",
        "isActive": "true",
        "isAdminActive": "true",
        "startDateTime":"1476205200000",
        "title": "Test greg T",
        "titleDate": "Tuesday, 11 Oct 8:00 PM",
        "type": "Games"
      }
    ]
    

    ...

    ... flutter

      Widget build(BuildContext context) {
        return new Scaffold(
            appBar: new AppBar(
              title: new Text("Load local JSON file"),
            ),
            body: new Container(
              child: new Center(
                // Use future builder and DefaultAssetBundle to load the local JSON file
                child: new FutureBuilder(
                    future: DefaultAssetBundle.of(context)
                        .loadString('assets/data/ckevents_data.json'),
                    builder: (context, snapshot) {
                      // Decode the JSON
                      var newData = json.decode(snapshot.data.toString());
    
                      return new ListView.builder(
                        // Build the ListView
                        itemBuilder: (BuildContext context, int index) {
                          return new Card(
                            child: new Column(
                              crossAxisAlignment: CrossAxisAlignment.stretch,
                              children: <Widget>[
                                new Text("Title: " + newData[index]['title'],
                                    style: new TextStyle(
                                        fontSize: 20.0, color: Colors.blue)),
                                new Text(
                                    "Description: " +
                                            ((newData[index].containsKey('description')) ? ('') : (newData[index]['description'])),
                                    style: new TextStyle(
                                        fontSize: 10.0, color: Colors.pink)),
                                new Text("Categorie: " + newData[index]['type'],
                                    style: new TextStyle(
                                        fontSize: 15.0, color: Colors.red)),
                                new Text(
                                    "Date: " +
                                        DateTime.fromMillisecondsSinceEpoch(
                                                newData[index]['startDateTime'])
                                            .add(Duration(days: 700))
                                            .toString(),
                                    style: new TextStyle(
                                        fontSize: 10.0, color: Colors.black))
                              ],
                            ),
                          );
                        },
                        itemCount: newData == null ? 0 : newData.length,
                      );
                    }),
              ),
            ));
      }
    }
    

    ...

  • dev_RGT
    dev_RGT almost 5 years
    Hello, Thank you for your fast reüply. I tried already this solution. Maybe I do somthing wrong. With your solution I have still an error, only the first Item is displayed and after I have message on the phone : Invalid Argumet(s) And in VSCode, I have theerror at same line as before. Merci Julien, other ideas from were is coming my issue ?
  • dev_RGT
    dev_RGT almost 5 years
    see my reply upper
  • dev_RGT
    dev_RGT almost 5 years
    Hi, Thank you for the reply, I tried already a solution like this, my class is already existing and it should be the next step to use it, but when I tried to use it I had first problem to create my list from a json file in assets. No idea why, maybe not right function to read the file and create the list ? It why I tried first a simplified approach and I get the issue with missing properties with no way to test it and skip it if not present.
  • dev_RGT
    dev_RGT almost 5 years
    Thank you for the place where I have to put it, but which function I have to use to read a File. In your solution data could be a file ? or do I have to use a function like: String data = await DefaultAssetBundle.of(context).loadString("assets/data/ckeve‌​nts_data.json"); and then do like you do for the list ?
  • Julien Lachal
    Julien Lachal almost 5 years
    as far as I see, in your code, you use the ternary ? operator. In this answer, I tell you to use the null coalesce operator ?? it's different. Have you tries it too?