0

Im trying to stream data from a JSON file I have into my app using StreamController in my case I want to constantly update the balance. I think its failing on reloading the file, it might be loading only the first time and that could why it is not updating the number, also because when i press hot reload it gets the correct value

  Stream<double> initBalance() async* {
    final response = await rootBundle
        .loadString('lib/assets/data.json')
        .then((jsonStr) => jsonDecode(jsonStr));

    yield double.parse(response['balance']);
  }

  MainController mainController;

  StreamController<double> streamController;

  @override
  void initState() {
    super.initState();
    this.mainController = new MainController();
    this.streamController = new StreamController();
    getData();
  }

  getData() {
    Timer.periodic(Duration(seconds: 1), (timer) async {
      var test = this.mainController.initBalance();
      this.streamController.sink.addStream(test);
    });
  }

1 Answers1

0

Are you using stream builder? because initstate will work once if you don't call setstate, but stream builder can change via stream or you need to call setstate every time you want to change data.

It should be like this:

StreamBuilder<double>(
          stream: getData(),
          builder: (BuildContext context, AsyncSnapshot<int> snapshot) {....})
Lunedor
  • 1,410
  • 1
  • 14
  • 33
  • Yes, im using StreamBuilder with my stream like this `StreamBuilder( stream: streamController.stream, builder: (context, snapshot) { if (snapshot.hasData) { return Text( '${_formatCurrency.format(snapshot.data)}', style: TextStyle(fontSize: 30, color: Colors.white54), ); } else { return Center(child: CircularProgressIndicator()); } }),` – Dani Barroso May 13 '20 at 09:29
  • The problem is you are using getData which has timer in initstate, that's why it only takes data one time, you can change your stream of your builder like this and try? stream: Stream.periodic(Duration(seconds: 1)) .asyncMap((i) => getData()), – Lunedor May 13 '20 at 13:08
  • I've tried and it doesn't works, the thing is that the periodic works but I dont think its reloading the data from the file, only when i hot reload the app it gets updated. Maybe its not the correct way to store my data – Dani Barroso May 13 '20 at 13:49
  • You are right this can be the reason of problem, it reads file just once and doesn't re-read it's updated situation, this probably would work with an api result but for stream of local files I am not sure it can be a solution for you but there is detail information here: https://stackoverflow.com/questions/51136512/flutter-reading-a-file-as-a-stream – Lunedor May 13 '20 at 13:54
  • I've been testing and if I do this `Timer.periodic(Duration(seconds: 2), (timer) async { var response = await rootBundle .loadString('lib/assets/data.json') .then((value) => jsonDecode(value)); print(response['balance']); });` to test if it changes, it gets the same values – Dani Barroso May 13 '20 at 13:56
  • Is it possible to reload assets while app is running? – Dani Barroso May 13 '20 at 15:13
  • you already use rootBundle so I would assume that should handle the changes, you can try to clear cache with `await rootBundle.evict('lib/assets/data.json')` before load asset in your function, maybe that will reload it. – Lunedor May 13 '20 at 15:27