Home > Back-end >  Flutter - Dart Unhandled Exception: type 'Blob' is not a subtype of type 'String'
Flutter - Dart Unhandled Exception: type 'Blob' is not a subtype of type 'String'

Time:06-28

I am trying to build an application in which I want to show some data in a chart. I'm fetching my data from a database, and want to structure it for use in a FutureBuilder widget and then render a line chart with multiple lines using syncfusion_flutter_charts: ^20.1.61.

In the method where I try to structure my data in a list, so I can display multiple lines, I get the following error:

[ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: type 'Blob' is not a subtype of type 'String', stack trace: #0

I tried casting the scores[i]['name'] as a String, which didn't help. I guess I have a hard time understanding what the Blob type is and why it occurs.

Code below - and methods for database calls and fetching my data is below that. Added a comment on the line where the exception happens. Any help is greatly appreciated.

import 'database.dart';

import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:syncfusion_flutter_charts/sparkcharts.dart';

class BanditData {
  BanditData(this.name, this.date, this.score);

  final String name;
  final String date;
  final int score;
}

class MyStatsPage extends StatefulWidget {
  const MyStatsPage({Key? key}) : super(key: key);

  @override
  MyStatsPageState createState() {
    return MyStatsPageState();
  }
}

class MyStatsPageState extends State<MyStatsPage> {
  final database = Database();

  Future<List<List<BanditData>>> getBanditData() async {
    var dates = await database.getDistinctDatesList();
    var scores = await database.createScoreDataStruct();
    var bandits = await database.getBandits();

    List<List<BanditData>> banditData = [];

    for (var item in bandits) {
      List<BanditData> temp = [];
      for (var i = 0; i < scores.length; i  ) { /* <--- Exception happens on this line */
        BanditData bandit =
            BanditData(scores[i]['name'], dates[i], scores[i]['score'][i]);
        temp.add(bandit);
      }
      banditData.add(temp);
    }

    print(banditData);

    return banditData;
  }

  @override
  Widget build(BuildContext context) {
    const appTitle = "Stats";

    return Scaffold(
        appBar: AppBar(
            title: const Text(
          appTitle,
          style: TextStyle(fontSize: 25, fontWeight: FontWeight.w700),
        )),
        body: FutureBuilder(
            future: getBanditData(),
            builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
              if (snapshot.connectionState == ConnectionState.waiting) {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              } else {
                if (snapshot.hasError) {
                  return ErrorWidget(Exception(
                      'Error occured when fetching data from database'));
                } else if (!snapshot.hasData) {
                  return const Center(child: Text('No data found.'));
                } else {
                  final _scores = snapshot.data![0];
                  final _dates = snapshot.data![1];

                  return Column(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      Expanded(
                          child: SfCartesianChart(
                        primaryXAxis: CategoryAxis(),
                        series: const <ChartSeries>[
                          /* Line charts here, when the data structure works */
                        ],
                      ))
                    ],
                  );
                }
              }
            }));
  }
}

Database code:

import 'dart:async';

import 'package:intl/intl.dart';
import 'package:mysql1/mysql1.dart';

class Database {
  final dateFormat = DateFormat('yyyy-MM-dd');

  Future<MySqlConnection> connect() async {
    var settings = ConnectionSettings(
      /* REMOVED */
    );

    var conn = await MySqlConnection.connect(settings);
    return conn;
  }

  Future<List<Map<String, dynamic>>> getBandits() async {
    List<Map<String, dynamic>> items = <Map<String, dynamic>>[];
    dynamic conn = await connect();

    var results = await conn.query('select * from bandit');

    for (var row in results) {
      items.add({'value': row["ID"], 'label': row["bandit"]});
    }

    await conn.close();

    return items;
  }

  void insertScore(id, date, course, score) async {
    dynamic conn = await connect();

    String query1 =
        "insert into test_score (Bandit_ID, Bane, dato, Scores) values (?, ?, ?, ?)";

    await conn.query(query1, [id, course, date, score]);

    conn.close();
  }

  Future<void> updateDbActive1(id) async {
    Future.delayed(const Duration(milliseconds: 500), () async {
      dynamic conn = await connect();

      String query = "UPDATE test_score SET IkkeAktiv = 1 WHERE Bandit_ID = ?";

      await conn.query(query, [id]);

      conn.close();
    });
  }

  Future<void> updateDbActive2(id) async {
    Future.delayed(const Duration(milliseconds: 500), () async {
      dynamic conn = await connect();

      String query =
          "UPDATE test_score SET IkkeAktiv = 0 WHERE Bandit_ID = ? ORDER BY Scores DESC LIMIT 10";

      await conn.query(query, [id]);

      conn.close();
    });
  }

  Future<List<String>> getDistinctDatesList() async {
    List<String> dates = [];
    dynamic conn = await connect();

    String query =
        "SELECT DISTINCT dato FROM test_score WHERE IkkeAktiv = 0 ORDER BY dato ASC";

    var result = await conn.query(query);
    for (var row in result) {
      dates.add(dateFormat.format(row["dato"]).toString());
    }

    conn.close();

    return dates;
  }

  Future<List<int>> getPlayerScoreFromDate(id) async {
    dynamic conn = await connect();

    var dateList = await getDistinctDatesList();
    var scores = <int>[];

    String query =
        "SELECT * FROM test_score WHERE Bandit_ID = ? AND IkkeAktiv = 0 ORDER BY dato ASC";

    var result = await conn.query(query, [id]);

    var score = 0;
    for (var date in dateList) {
      var count = 0;
      for (var row in result) {
        if (date == dateFormat.format(row["dato"]).toString()) {
          var value = row["Scores"];
          score  = value as int;
          scores.add(score);
          break;
        } else {
          count  ;
          if (count == result.length) {
            scores.add(score);
          }
          continue;
        }
      }
    }

    conn.close();

    return scores;
  }

  Future<List<Map<String, dynamic>>> createScoreDataStruct() async {
    List<Map<String, dynamic>> playerScoresSum = <Map<String, dynamic>>[];

    var bandits = await getBandits();

    for (var bandit in bandits) {
      playerScoresSum.add({
        'value': bandit['value'],
        'name': bandit['label'],
        'scores': await getPlayerScoreFromDate(bandit['value'])
      });
    }

    return playerScoresSum;
  }
}

CodePudding user response:

Seems like it could be fixed by adding .toString() in the method that fetches the data from the database.

Future<List<Map<String, dynamic>>> createScoreDataStruct() async {
    List<Map<String, dynamic>> playerScoresSum = <Map<String, dynamic>>[];

    var bandits = await getBandits();

    for (var bandit in bandits) {
      playerScoresSum.add({
        'value': bandit['value'],
        'name': bandit['label'].toString(), // <------
        'scores': await getPlayerScoreFromDate(bandit['value'])
      });
    }

    print(playerScoresSum);

    return playerScoresSum;
  }
  • Related