Flutter Provider with FutureBuilder

49 Views Asked by At

I'm trying to use a ChangeNotifier in combination with a FutureBuilder to display Data from a server. The data is in JSON and base63 decoded. I have the following SetUp:

A FutureNotifier Class

class FutureNotifier extends ChangeNotifier {
  Future<String> future = Future.value("keinWert");
  Future<String> get getFuture => future;

  void setFuture(Future<String> newFuture) {
    future = newFuture;
    notifyListeners();
  }
}

A helper Class for decoding

class ResponseDecoder {
  late String response;
  late Map<String, dynamic> jsonDecoded;

  ResponseDecoder();

  void setResponse(String? response) {
    this.response = response!;
    jsonDecoded = decodeData();
    print("done");
  }

  Map<String, dynamic> decodeData() {
    Map<String, dynamic> decodedData = json.decode(response);
    return decodedData;
  }

  Uint8List getBytes(String? type) {
    if (type == null) {
      throw ArgumentError('Type cannot be null');
    } else if (jsonDecoded.containsKey(type)) {
      dynamic value = jsonDecoded[type];
      if (value is String) {
        return base64.decode(jsonDecoded[type]!);
      } else {
        throw ArgumentError("Invalid Data type");
      }
    } else {
      throw ArgumentError('Type not found');
    }
  }
}

The Outputbox class

class OutputBox extends StatelessWidget {
  final Key key;
  OutputBox({
    required this.key,
    required this.name,
  });
  final String name;
  final ResponseDecoder responseDecoder = ResponseDecoder();

  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
       
        Consumer<FutureNotifier>(builder: (context, myChangeNotifier, _) {
          return SizedBox(
            height: 100,
            child: FutureBuilder<String>(
              future: myChangeNotifier.future,
              builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
                Widget child;
                if (snapshot.connectionState == ConnectionState.done) {
                  if (snapshot.hasError) {
                    child = Container(
                      width: 300,
                      height: 50,
                      decoration: BoxDecoration(
                        border: Border.all(
                          color: Colors.red,
                          width: 2,
                        ),
                      ),
                      child: const Center(
                        child: Text(
                          'ERROR',
                          style: TextStyle(color: Colors.red),
                        ),
                      ),
                    );
                    print('Error ${snapshot.error} occured');
                  } else {
                    if (snapshot.data == "keinWert") {
                      child = const Text("Kein Wert bis jetzt");
                    } else {
                      responseDecoder.setResponse(snapshot.data);

                      if (name == "AI Generated") {
                        child = Image.memory(
                            responseDecoder.getBytes("model_result"));
                      } else if (name == "Groundtruth") {
                        child = Image.memory(
                            responseDecoder.getBytes("groundtruth"));
                      } else if (name == "Difference Field") {
                        child = Image.memory(
                            responseDecoder.getBytes("error_measure"));
                      } else {
                        child = Text("ERROR");
                      }
                    }
                  }
                } else {
                  child = const SizedBox(
                    width: 60,
                    height: 60,
                    child: CircularProgressIndicator(),
                  );
                }
                return child;
              },
            ),
          );
        }),
        const SizedBox(
          width: 20,
        ),
        Text(
          "$name",
          textScaleFactor: 1.2,
        ),
      ],
    );
  }
}

The setter for the Future is just a ChangeNotifierProvider with a Button that uses "setFuture" to set the Future and is not the cause for all this.

This works perfectly fine for the first time I press the Button and send Data. The FutureBuilder "loads" and then displays the correct Image. However, when I press again with different Inputs the FutureBuilder loads again (so the build method is correctly triggered again through the ChangeNotifier) HOWEVER, the Image is still the same. In fact the future seems to still be the same (which I found out through printing) so it led me to believe something is wrong with my Provider/Notifier Setup? I cant seem to figure it out at all.

I tried various forms of Provider notations, none of them changed anything at all.

0

There are 0 best solutions below