2

I am new to Flutter and I am getting this error: A non-null String must be provided to a Text widget. I tried to fix it but it won't. The api responds fine, here is the url: https://appiconmakers.com/demoMusicPlayer/API/getallcategories

Here is the code that I wrote,

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert';

class CategoryTab extends StatefulWidget {
     @override
     _CategoryTabState createState() => _CategoryTabState();
}

class _CategoryTabState extends State<CategoryTab> {
    @override
    void initState() {
        // TODO: implement initState
        super.initState();
    }

    Future<List<CategoryList>> _getUsers() async {

        var data = await http.get("https://appiconmakers.com/demoMusicPlayer/API/getallcategories");

        var jsonData = json.decode(data.body);

        List<CategoryList> cat = [];

        for (var u in jsonData) {

            CategoryList categoryList = CategoryList(u["categoryId"], u["categoryName"], u["parentCategoryId"], u["categoryStatus"], u["createdDate"]);

            cat.add(categoryList);

        }
        print("=================================");

        print(cat.length);

        return cat;

    }

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: Text("Categories", style: TextStyle(color:Colors.black)),
                backgroundColor: Colors.white,
        ), body: 
        Container(
            child: FutureBuilder(
                future: _getUsers(),
                builder: (BuildContext context, AsyncSnapshot snapshot) {
                    print(snapshot.data);
                    if (snapshot.data == null) {
                        return Container(
                            child: Center(child: Text("Loading..."))
                        );
                    } else {
                        return ListView.builder(
                            itemCount: snapshot.data.length,
                            itemBuilder: (BuildContext context, int index) {
                                return ListTile(
                                    leading: CircleAvatar(),
                                    title: Text(snapshot.data[index].categoryName,
                                    // subtitle: Text(snapshot.data[index].categoryId),
                                );
                            },
                        );
                    }
                ),
            ),
        );
    }
}

class CategoryList {
    String categoryId;
    String categoryName;
    String parentCategoryId;
    String categoryStatus;
    String createdDate;

    CategoryList(this.categoryId, this.categoryName, this.parentCategoryId, this.categoryStatus, this.createdDate);
}

The debug section also gives me this result:

 [        ] flutter: =================================
 [        ] [DEVICE LOG] 2020-07-29 08:05:00.688910+0300  localhost Runner[20673]: (Flutter)      flutter: 9
 [        ] flutter: 9
 [        ] [DEVICE LOG] 2020-07-29 08:05:00.690942+0300  localhost Runner[20673]: (Flutter)  flutter:
[Instance of 'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList', Instance of
'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList', Instance of  'CategoryList',
Instance of 'CategoryList', Instance of 'CategoryList']
[        ] flutter: [Instance of 'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList',
Instance of 'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList', Instance of
 'CategoryList', Instance of 'CategoryList', Instance of 'CategoryList']
 [   +1 ms] [DEVICE LOG] 2020-07-29 08:05:00.692566+0300  localhost Runner[20673]: (Flutter)   flutter:
 Another exception was thrown: A non-null String must be provided to a Text widget.
 [        ] flutter: Another exception was thrown: A non-null String must be provided to a  Text widget.
Manaus
  • 407
  • 5
  • 9
haptomee
  • 59
  • 10

4 Answers4

1

just check the answer

model class for the json:

// To parse this JSON data, do
//
//     final categoryList = categoryListFromJson(jsonString);

import 'dart:convert';

List<CategoryList> categoryListFromJson(String str) => List<CategoryList>.from(json.decode(str).map((x) => CategoryList.fromJson(x)));

String categoryListToJson(List<CategoryList> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class CategoryList {
    CategoryList({
        this.categoryId,
        this.categoryName,
        this.parentCategoryId,
        this.categoryStatus,
        this.createdDate,
        this.subcategory,
    });

    String categoryId;
    String categoryName;
    String parentCategoryId;
    String categoryStatus;
    DateTime createdDate;
    List<CategoryList> subcategory;

    factory CategoryList.fromJson(Map<String, dynamic> json) => CategoryList(
        categoryId: json["category_id"],
        categoryName: json["category_name"],
        parentCategoryId: json["parent_category_id"],
        categoryStatus: json["category_status"],
        createdDate: DateTime.parse(json["created_date"]),
        subcategory: List<CategoryList>.from(json["subcategory"].map((x) => CategoryList.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "category_id": categoryId,
        "category_name": categoryName,
        "parent_category_id": parentCategoryId,
        "category_status": categoryStatus,
        "created_date": createdDate.toIso8601String(),
        "subcategory": List<dynamic>.from(subcategory.map((x) => x.toJson())),
    };
}



ui for it :

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:json_parsing_example/models.dart';
import 'package:http/http.dart' as http;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: HomePage());
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  double value;
  @override
  void initState() {
    super.initState();
  }

  Future<List<CategoryList>> _getUsers() async {
    var data = await http
        .get("https://appiconmakers.com/demoMusicPlayer/API/getallcategories");

    final categoryList = categoryListFromJson(data.body);
    List<CategoryList> cat = [];

    categoryList.forEach((element) {
      cat.add(CategoryList(
          categoryId: element.categoryId,
          categoryName: element.categoryName,
          parentCategoryId: element.parentCategoryId,
          categoryStatus: element.categoryStatus,
          createdDate: element.createdDate.toString()));
    });

    print("=================================");

    print(cat.length);

    return cat;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "Categories",
          style: TextStyle(color: Colors.black),
        ),
        backgroundColor: Colors.white,
      ),
      body: Container(
        child: FutureBuilder(
          future: _getUsers(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            print(snapshot.data);

            if (snapshot.data == null) {
              return Container(child: Center(child: Text("Loading...")));
            } else {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                    leading: CircleAvatar(),
                    title: Text(
                      snapshot.data[index].categoryName,
                      // subtitle: Text(snapshot.data[index].categoryId
                    ),
                  );
                },
              );
            }
          },
        ),
      ),
    );
  }
}

class CategoryList {
  String categoryId;
  String categoryName;
  String parentCategoryId;
  String categoryStatus;
  String createdDate;

  CategoryList(
      {this.categoryId,
      this.categoryName,
      this.parentCategoryId,
      this.categoryStatus,
      this.createdDate});
}

Let me know if it works.

Sagar Acharya
  • 3,397
  • 4
  • 12
  • 34
0

Just do the following updates:

title: Text(snapshot.data[index].categoryName ?? '',
              // subtitle: Text(snapshot.data[index].categoryId
              ),

Now if the snapsho.data[index].categoryName is null, the empty string will be assigned to the text widget.

In case you want to see if data is there or not, then just print the snapshot.data and you can find out if the data is there or not.

Haroon khan
  • 1,018
  • 2
  • 15
  • 27
0

Replace
title: Text(snapshot.data[index].categoryName,
with
title: Text(snapshot.data[index].categoryName ?? “Some Text To Display if Null”

That should do it. The value after the ?? will replace the previous value if it’s null

Check this answer for more info on the ?? operator

lenz
  • 2,193
  • 17
  • 31
0

Replace this code

CategoryList categoryList = CategoryList(u["categoryId"], u["categoryName"], u["parentCategoryId"], u["categoryStatus"], u["createdDate"]);

with

CategoryList categoryList = CategoryList(u["category_id"], u["category_name"], u["parent_category_id"], u["category_status"], u["created_date"]);

shubham chhimpa
  • 263
  • 3
  • 10