Why is my "Data"."data" not updated in ChangeNotifier class using ChangeNotifierProvider?

Issue

I am new to flutter.
I want to ask why when my text field’s onChange did not trigger: “Provider.ofContext).updateData(newString);”.
The value of my Provider.of(context).data is not updated and with the 2 print statements, only ‘called1’ is always printed out.

Here is the code:
import ‘package:flutter/material.dart’;
import ‘package:provider/provider.dart’;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Data>(
      create: (_) => Data(),
      lazy: false,
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: Text(Provider.of<Data>(context).data),
          ),
          body: Level2(),
        ),
      ),
    );
  }
}


class Level2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        MyTextField(),
      ],
    );
  }
}

class MyTextField extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextField(onChanged: (newString) {
      print('called1');
      Provider.of<Data>(context).updateData(newString);
      print('called2');
    });
  }
}

class Data extends ChangeNotifier {
  String data = '1234567890';

  void updateData(newString) {
    data = newString;
    notifyListeners();
  }
}

Solution

You are trying to access provider in same widget where you are declaring, which is not right way to do, provider must declare in above widget where you are accessing.

Moreover always use provider data by variable(as used in MyTextField widget) other wise it will not work.

Following code may help you to understand more.

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Data>(
      create: (_) => Data(),
      child: MaterialApp(home: Level1()),
    );
  }
}

class Level1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(Provider.of<Data>(context).data),
      ),
      body: Level2(),
    );
  }
}

class Level2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        MyTextField(),
      ],
    );
  }
}

class MyTextField extends StatelessWidget {
  var dataprovider;
  @override
  Widget build(BuildContext context) {
    dataprovider = Provider.of<Data>(context);
    return TextField(
      onChanged: (newString) {
        print(dataprovider.data);
        dataprovider.updateData(newString);
        print('called2');
      },
    );
  }
}

class Data extends ChangeNotifier {
  String data = '1234567890';

  void updateData(newString) {
    print("cds");
    data = newString;
    notifyListeners();
  }
}

Answered By – Viren V Varasadiya

Answer Checked By – Marilyn (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.