1

I have the following problem. I want to read a variable from class1. The command to read the variable comes from another class. However it returns null. This is not my actual code, however I wrote a demo app to illustrate the problem: when I press a button, it should add 5 to a variable called "number" stored in class1 and will be displayed in a text widget using the Provider Package. Then I want to read the variable "number" from another class. To show if this is working I put a print statement in the onPressed Function, to show if my class2 got the value from class1. However I always get null returned and I can't figure out why.

In short, this is my onPressed Function and the two classes:

onPressed: () {
                class1.addNumber(5);
                print(class1.number);
                print(class2.numberFromClass1);
              },


class Class1 extends ChangeNotifier {
  int number;

  void addNumber(value) {
    number = number + value;
    notifyListeners();
  }

  get getNumber {
    return number;
  }
}

class Class2 extends ChangeNotifier {
  int numberFromClass1;

  void getNumberFromClass1() {
    numberFromClass1 = Class1().getNumber;
    print(numberFromClass1);
    notifyListeners();
  }
}

Either the variable "number" in class1 is not changed or the class2 can't read the variable "number" from class1 and store it in its own variable.

Thanks for helping!

And this is the whole demo program:

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

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<Class1>(
          create: (context) => Class1(),
        ),
        ChangeNotifierProxyProvider<Class1, Class2>(
            update: (BuildContext context, class1, class2) => Class2(),
            create: (context) => Class2()),
      ],
      child: MaterialApp(initialRoute: HomePage.id, routes: {
        HomePage.id: (context) => HomePage(),
      }),
    );
  }
}

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

class HomePage extends StatelessWidget {
  static const String id = 'home_page';

  @override
  Widget build(BuildContext context) {
    return Consumer2<Class1, Class2>(
      builder: (context, class1, class2, child) {
        return Scaffold(
          backgroundColor: Colors.blueAccent,
          body: Container(
            alignment: Alignment.center,
            color: Colors.blueAccent,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(class1.number.toString()),
                SizedBox(height: 50),
                MaterialButton(
                  color: Colors.deepOrangeAccent,
                  height: 100,
                  minWidth: 100,
                  child: Text(
                    '5',
                    style: TextStyle(fontSize: 40),
                  ),
                  onPressed: () {
                    class1.addNumber(5);
                    print(class1.number);
                    print(class2.numberFromClass1);
                  },
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

class Class1 extends ChangeNotifier {
  int number;

  void addNumber(value) {
    number = number + value;
    notifyListeners();
  }

  get getNumber {
    return number;
  }
}

class Class2 extends ChangeNotifier {
  int numberFromClass1;

  void getNumberFromClass1() {
    numberFromClass1 = Class1().getNumber;
    print(numberFromClass1);
    notifyListeners();
  }
}

1 Answers1

0

You should make it async when you click it makes together and in the Class2 here newNumber is still 0. Use Future method and use whenComplete(() => null) after.

Mustafa yıldiz
  • 325
  • 1
  • 8
  • Hello Mustafa, thanks a lot for your answer. I tried your solution, however I still get a 0 returned from my class2 even with the Future method. I checked some examples with the ChangeNotifierProxyProvider and couldn't find any code, which uses the Future, async and await in combination with it. Maybe I'am do something wrong (most probably as I am new to programming) or do I need another Provider to get it work, like the Future Provider? – strato_cruiser Jan 18 '21 at 08:25
  • Simple in your onPress call a Future method. await calculateNewNumber().then((value) {}).whenComplete(() { calculateNewNumber(); }); – Mustafa yıldiz Jan 18 '21 at 09:54
  • I still get a 0 printed when I call the doSomethingWithClass1Data(). However I really appreciate your help. This is my onPressed function: onPressed: () async { await class1 .calculateNewNumber(5) .then((value) {}) .whenComplete(() { Class2().doSomethingWithClass1Data(); Is there also a way to get the data from class1 with a call I do in class2 instead of doing this in the inPressed Function? – strato_cruiser Jan 18 '21 at 11:12