venkatesh munaga
venkatesh munaga

Reputation: 15

Can't add the data to list using Provider in flat button on flutter

I'm using provider 4.3.2 in this flutter code, this is a simple flutter app that has a text filed, flat button, and a list view builder that contain the text widget. I created a class ListData that has the list and is shown in the list view builder using provider. Here is the problem, I created a addData method in the ListData class. I used this method to add data to list using provider in the onPressed method of flat button add it is throwing error, unable to find. the solution for this problem. Also this is a short form of my main app

import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String data;
    return ChangeNotifierProvider(
      create: (context) => ListData(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text("list"),
          ),
          body: Column(
            children: [
              TextField(
                onChanged: (value) => data = value,
              ),
              FlatButton(
                child: Text("Add"),
                color: Colors.blue,
                onPressed: () {
                  Provider.of<ListData>(context).addData(data);
                },
              ),
              Expanded(
                child: MyListView(),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class MyListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, index) {
        return Text(Provider.of<ListData>(context).listData[index]);
      },
      itemCount: Provider.of<ListData>(context).listCount,
    );
  }
}

class ListData extends ChangeNotifier {
  List _listData = [
    'Hello',
    "hi",
  ];

  UnmodifiableListView get listData {
    return UnmodifiableListView(_listData);
  }

  int get listCount {
    return _listData.length;
  }

  void addData(String data) {
    _listData.add(data);
    notifyListeners();
  }
}

Upvotes: 1

Views: 1986

Answers (2)

Er1
Er1

Reputation: 2758

You need to wrap your FlatButton in a Consumer widget because Provider.of is called with a BuildContext that is an ancestor of the provider.

return ChangeNotifierProvider(
    create: (_) => ListData(),
    child: Consumer<ListData>(
      builder: (_, listData, __) => FlatButton(onPressed: () => listData.addData(data)),
    },
  );

Check out this to learn more with simple examples to help you understand why you get the error and how to use it.

https://pub.dev/documentation/provider/latest/provider/Consumer-class.html

Upvotes: 1

chunhunghan
chunhunghan

Reputation: 54367

You can copy paste run full code below
You need Builder and listen: false
code snippet

Builder(builder: (BuildContext context) {
        return FlatButton(
          child: Text("Add"),
          color: Colors.blue,
          onPressed: () {
            Provider.of<ListData>(context, listen: false).addData(data);
          },
        );
      }),

working demo

enter image description here

full code

import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String data;
    return ChangeNotifierProvider(
      create: (context) => ListData(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text("list"),
          ),
          body: Column(
            children: [
              TextField(
                onChanged: (value) => data = value,
              ),
              Builder(builder: (BuildContext context) {
                return FlatButton(
                  child: Text("Add"),
                  color: Colors.blue,
                  onPressed: () {
                    Provider.of<ListData>(context, listen: false).addData(data);
                  },
                );
              }),
              Expanded(
                child: MyListView(),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class MyListView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (context, index) {
        return Text(Provider.of<ListData>(context).listData[index]);
      },
      itemCount: Provider.of<ListData>(context).listCount,
    );
  }
}

class ListData extends ChangeNotifier {
  List _listData = [
    'Hello',
    "hi",
  ];

  UnmodifiableListView get listData {
    return UnmodifiableListView(_listData);
  }

  int get listCount {
    return _listData.length;
  }

  void addData(String data) {
    _listData.add(data);
    notifyListeners();
  }
}

Upvotes: 2

Related Questions