Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

The data from file is not updated in my App

I build the app that should return the tree of blocks connected to each other. I would like to have the possibility to save the info after user made the changes on the phone. I use for this getApplicationDocumentsDirectory() to get the path. After the user made changes and closes the app, he or she can open it and see all his or her progress. So I try to read the file asynchronously in initState()

Could you help me with that? (My code is below; Now it returns type error, but I don’t know how to solve it)

main.dart

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:graphview/GraphView.dart';
import 'dart:math';
import 'MyNode.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
        home: TreeViewPage(),
      );
}

class TreeViewPage extends StatefulWidget {
  @override
  _TreeViewPageState createState() => _TreeViewPageState();
}

var parsedJson;

final Graph graph = Graph()..isTree = true;
SugiyamaConfiguration builder = SugiyamaConfiguration();
// builder
//   ..levelSeparation = (150)
//   ..nodeSeparation = (100)
//   ..orientation = (SugiyamaConfiguration.ORIENTATION_TOP_BOTTOM);
List<MyNode> ListMyNode = [];
int nodesCount = 0;

String text_from_init_state = "no_data";

class _TreeViewPageState extends State {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
        future: parsedJson,
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (parsedJson == null) {
            return Center(
              child: CircularProgressIndicator(
                  backgroundColor: Colors.red,
                  valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)),
            );
          }

          return Column(
            mainAxisSize: MainAxisSize.max,
            children: [
              Text(text_from_init_state),
              Expanded(
                child: InteractiveViewer(
                  constrained: false,
                  boundaryMargin: EdgeInsets.all(300),
                  minScale: 0.01,
                  maxScale: 5.6,
                  child: GraphView(
                    graph: graph,
                    algorithm: SugiyamaAlgorithm(builder),
                    paint: Paint()
                      ..color = Colors.green
                      ..strokeWidth = 1
                      ..style = PaintingStyle.stroke,
                    builder: (Node node) {
                      // I can decide what widget should be shown here based on the id
                      var a = node.key!.value as int;
                      return rectangleWidget(a);
                    },
                  ),
                ),
              ),
            ],
          );
        },
      ),
    );
  }



Widget rectangleWidget(int a) {
    TextEditingController textController = TextEditingController();
    if (ListMyNode[a - 1].text != "") {
      textController.text = ListMyNode[a - 1].text;
    }

    return InkWell(
      onTap: () {
        print("a" + a.toString());
      },
      child: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(4),
          boxShadow: [
            BoxShadow(color: Colors.blue, spreadRadius: 1),
          ],
        ),
        child: Column(
          children: [
            Container(
              // height: 80,
              width: 80,
              child: TextField(
                keyboardType: TextInputType.multiline,
                maxLines: null,
                controller: textController,
                decoration: const InputDecoration(),
                onChanged: (v) async {
                  await ListMyNode[a - 1].UpdateText(v, ListMyNode);
                },
              ),
            ),
            Container(
              alignment: Alignment.bottomRight,
              child: IconButton(
                icon: Icon(Icons.add_box_rounded),
                iconSize: 24,
                onPressed: () async {
                  nodesCount++;
                  final newNode = Node.Id(nodesCount);
                  var edge = graph.getNodeAtPosition(a - 1);
                  graph.addEdge(edge, newNode);
                  text_from_init_state = await readJson();
                  setState(() {
                    MyNode b = MyNode(nodesCount, "");
                    ListMyNode.add(b);
                  });
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void initState() {
    readJson2().whenComplete(() {
      print("PArsed Json: " + parsedJson.toString());

      if (parsedJson == "{}") {
        final node1 = Node.Id(1);
        final node2 = Node.Id(2);
        MyNode block0 = MyNode(nodesCount, "empty1");
        nodesCount++;
        MyNode block1 = MyNode(nodesCount, "empty2");
        nodesCount++;
        ListMyNode.add(block0);
        ListMyNode.add(block1);
        graph.addEdge(node1, node2);
      } else {
        final node1 = Node.Id(1);
        final node2 = Node.Id(2);
        MyNode block0 = MyNode(nodesCount, parsedJson.toString());
        nodesCount++;
        MyNode block1 = MyNode(nodesCount, "not_empty2");
        nodesCount++;
        ListMyNode.add(block0);
        ListMyNode.add(block1);
        graph.addEdge(node1, node2);
      }

      print("before setState: " + parsedJson);
      setState(() {});
      print("after setState: " + parsedJson);
    });
    super.initState();

    builder
      ..levelSeparation = (150)
      ..nodeSeparation = (100)
      ..orientation = (SugiyamaConfiguration.ORIENTATION_TOP_BOTTOM);
  }

  Future<void> readJson2() async {
    try {
      final file = await localFile();

      // Read the file
      final contents = await file.readAsString();

      parsedJson = contents;
    } catch (e) {
      // If encountering an error, return 0
      parsedJson = "{}";
    }
  }
}

MyNode.dart

import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

String ListMyNodeJSON(List<MyNode> lst) {
  Map<int, String> mapMyNodeJSON = {};
  for (int i = 0; i < lst.length; i++) {
    mapMyNodeJSON[lst[i].id] = lst[i].text;
  }
  return mapMyNodeJSON.toString();
}

Future<String> localPath() async {
  final directory = await getApplicationDocumentsDirectory();

  return directory.path;
}

Future<File> localFile() async {
  final path = await localPath();
  return File('$path/tree.json');
}

Future<File> writeJson(text) async {
  final file = await localFile();
  return file.writeAsString("$text");
}

Future<String> readJson() async {
  try {
    final file = await localFile();

    // Read the file
    final contents = await file.readAsString();

    return contents;
  } catch (e) {
    // If encountering an error, return 0
    return "{}";
  }
}

class MyNode {
  int id = 0;
  String text = "";

  MyNode(int id, String text) {
    this.id = id;
    this.text = text;
  }

  Future<void> UpdateText(String text, List<MyNode> lst) async {
    this.text = text;
    await writeJson(ListMyNodeJSON(lst));
  }

  String toString() {
    return this.id.toString() + "---" + this.text;
  }
}

>Solution :

I updated your code to show loading bar while fetching data and show blocks when completed. Now it gets the progress from file but it seems that you haven’t implemented game logic for resuming the progress yet. I find this an interesting project. Hope this code solves your problem and continue developing progress logic section.

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:graphview/GraphView.dart';
import 'dart:math';
import 'MyNode.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
        home: TreeViewPage(),
      );
}

class TreeViewPage extends StatefulWidget {
  @override
  _TreeViewPageState createState() => _TreeViewPageState();
}

final Graph graph = Graph()..isTree = true;
SugiyamaConfiguration builder = SugiyamaConfiguration();
// builder
//   ..levelSeparation = (150)
//   ..nodeSeparation = (100)
//   ..orientation = (SugiyamaConfiguration.ORIENTATION_TOP_BOTTOM);
List<MyNode> ListMyNode = [];
int nodesCount = 0;

String text_from_init_state = "no_data";

class _TreeViewPageState extends State {
  late String parsedJson;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
        future: readJson2(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: CircularProgressIndicator(
                  backgroundColor: Colors.red,
                  valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)),
            );
          } else if (snapshot.connectionState == ConnectionState.done) {
            parsedJson = snapshot.data as String;
            updateNode(parsedJson);
            return Column(
              mainAxisSize: MainAxisSize.max,
              children: [
                Text(text_from_init_state),
                Expanded(
                  child: InteractiveViewer(
                    constrained: false,
                    boundaryMargin: EdgeInsets.all(300),
                    minScale: 0.01,
                    maxScale: 5.6,
                    child: GraphView(
                      graph: graph,
                      algorithm: SugiyamaAlgorithm(builder),
                      paint: Paint()
                        ..color = Colors.green
                        ..strokeWidth = 1
                        ..style = PaintingStyle.stroke,
                      builder: (Node node) {
                        // I can decide what widget should be shown here 
                        //based on the id
                        var a = node.key!.value as int;
                        return rectangleWidget(a);
                      },
                    ),
                  ),
                ),
              ],
            );
          }
          return Center(
            child: Text(
              'Something went wrong!',
              style: TextStyle(
                color: Colors.red,
              ),
            ),
          );
        },
      ),
    );
  }

  void updateNode(String parsedReadJson2) {
    if (parsedReadJson2.isEmpty) {
      final node1 = Node.Id(1);
      final node2 = Node.Id(2);
      MyNode block0 = MyNode(nodesCount, "empty1");
      nodesCount++;
      MyNode block1 = MyNode(nodesCount, "empty2");
      nodesCount++;
      ListMyNode.add(block0);
      ListMyNode.add(block1);
      graph.addEdge(node1, node2);
    } else {
      final node1 = Node.Id(1);
      final node2 = Node.Id(2);
      MyNode block0 = MyNode(nodesCount, parsedReadJson2.toString());
      nodesCount++;
      MyNode block1 = MyNode(nodesCount, "not_empty2");
      nodesCount++;
      ListMyNode.add(block0);
      ListMyNode.add(block1);
      graph.addEdge(node1, node2);
    }
  }

  Widget rectangleWidget(int a) {
    TextEditingController textController = TextEditingController();
    if (ListMyNode[a - 1].text != "") {
      textController.text = ListMyNode[a - 1].text;
    }

    return InkWell(
      onTap: () {
        print("a$a");
      },
      child: Container(
        padding: EdgeInsets.all(20),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(4),
          boxShadow: [
            BoxShadow(color: Colors.blue, spreadRadius: 1),
          ],
        ),
        child: Column(
          children: [
            Container(
              // height: 80,
              width: 80,
              child: TextField(
                keyboardType: TextInputType.multiline,
                maxLines: null,
                controller: textController,
                decoration: const InputDecoration(),
                onChanged: (v) async {
                  await ListMyNode[a - 1].UpdateText(v, ListMyNode);
                },
              ),
            ),
            Container(
              alignment: Alignment.bottomRight,
              child: IconButton(
                icon: Icon(Icons.add_box_rounded),
                iconSize: 24,
                onPressed: () async {
                  nodesCount++;
                  final newNode = Node.Id(nodesCount);
                  var edge = graph.getNodeAtPosition(a - 1);
                  graph.addEdge(edge, newNode);
                  text_from_init_state = await readJson();
                  setState(() {
                    MyNode b = MyNode(nodesCount, "");
                    ListMyNode.add(b);
                  });
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void initState() {
    super.initState();

    builder
      ..levelSeparation = (150)
      ..nodeSeparation = (100)
      ..orientation = (SugiyamaConfiguration.ORIENTATION_TOP_BOTTOM);
  }

  Future<String> readJson2() async {
    try {
      final file = await localFile();

      // Read the file
      final contents = await file.readAsString();

      return contents;
    } catch (e) {
      // If encountering an error, return empty string
      return '';
    }
  }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading