Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
422 views
in Technique[技术] by (71.8m points)

flutter - The getter items was called on null

I am working on a simple ListView app that gets populated from the internet and storing in the database using Provider. But the ListView doesn't get populated. It was getting null on items getter. But after I changed with Consumer.

Now I got an error, The getter items was called on null.

stackoverflow

 ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (15505): The following NoSuchMethodError was thrown building FutureBuilder<void>(dirty, state:
I/flutter (15505): _FutureBuilderState<void>#7948f):
I/flutter (15505): The getter 'items' was called on null.
I/flutter (15505): Receiver: null
I/flutter (15505): Tried calling: items
I/flutter (15505): 
I/flutter (15505): The relevant error-causing widget was:
I/flutter (15505):   FutureBuilder<void>
I/flutter (15505):   file:///C:/Users/Admin/lib/main.dart:27:13
I/flutter (15505): 
I/flutter (15505): When the exception was thrown, this was the stack:
I/flutter (15505): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
I/flutter (15505): #1      _MyAppState.build.<anonymous closure> (package:list_cart_interview/main.dart:37:33)
I/flutter (15505): #2      _FutureBuilderState.build (package:flutter/src/widgets/async.dart:751:55)
I/flutter (15505): #3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4744:28)
I/flutter (15505): #4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4627:15)
I/flutter (15505): #5      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart

main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'models/product.dart';
import 'provider/product_provider.dart';
import 'widgets/list_item.dart';

void main() {
  runApp(
    MaterialApp(
      home: ChangeNotifierProvider.value(
        value: ProductsProvider(),
        child: MyApp(),
      ),
    ),
  );
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
          future: Provider.of<ProductsProvider>(context, listen: false)
              .getProducts(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(
                child: CircularProgressIndicator(),
              );
            }

            print(snapshot.data.items.length);
            if (snapshot.connectionState == ConnectionState.done) {
              return Consumer<ProductsProvider>(
                child: Center(
                  child: CircularProgressIndicator(),
                ),
                builder: (context, productProvider, child) =>
                    productProvider.items.length <= 0
                        ? child
                        : ListView.builder(
                            itemCount: productProvider.items.length,
                            itemBuilder: (context, index) {
                              return ListItem();
                            },
                          ),
              );
            }
            return Container();
          }),
    );
  }
}

product_provider.dart

import 'package:flutter/foundation.dart';
import 'package:http/http.dart';
import 'package:list_cart_interview/hellper/sqlite_helper.dart';
import 'dart:convert';
import '../models/product.dart';

class ProductsProvider with ChangeNotifier {
  List<Products> _items = [];

  List get items {
    return [..._items];
  }

  Future<void> getDataFromInternet() async {
    try {
      Response response = await get('https://jsonkeeper.com/b/YIDG');

      Map<String, dynamic> extractedData = jsonDecode(response.body);

      final length = extractedData['data']['products'].length;
      print(length);

      for (int i = 0; i < length; i++) {
        DatabaseHelper.insert({
          'id': extractedData['data']['products'][i]['prodCode'],
          'prodName': extractedData['data']['products'][i]['prodName'],
          'prodImage': extractedData['data']['products'][i]['prodImage'],
          'prodPrice': extractedData['data']['products'][i]['prodPrice'],
          'cartQuantity': 0,
        });
      }
    } catch (error) {
      throw (error);
    }
  }

  Future getProducts() async {
    await getDataFromInternet();
    final productsList = await DatabaseHelper.getProductsFromDB();
    print(" hbj ${productsList}");

    _items = productsList
        .map(
          (item) => Products(
            item['id'],
            item['prodName'],
            item['prodImage'],
            item['prodPrice'],
            item['cartQuantity'],
          ),
        )
        .toList();
    print('-items: ${_items}');
    notifyListeners();
  }
}

I think getProducts() method is making the problem in above code. Now getting an only child is this widget. Please help


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to check whether your snapshot.data has data or not before accessing the items.

if(snapshot.hasData) {
  // return your ListView
}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...