Flutter: passing future<int> as int to Charts - dart

I am making a mood checker application using flutter where user chose one of 5 emojis to tell their mood.
I want to display a PieChart with data emoji vs num of Days it has been chosen.
Problem is that I have to fetch data from sqflite Database to get numOfDays a particular emoji is chosen which will be of type Future but charts can't take Futures, I tried to use async-await but it didn't seem to work.
Error
E/flutter (27721): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: type 'Future<dynamic>' is not a subtype of type 'int'
E/flutter (27721): #0 _MoodChartState.initData (package:pro_app/journal/view/mood_chart.dart:36:24)
E/flutter (27721): #1 _AsyncAwaitCompleter.start (dart:async/runtime/libasync_patch.dart:49:6)
E/flutter (27721): #2 _MoodChartState.initData (package:pro_app/journal/view/mood_chart.dart:31:16)
E/flutter (27721): #3 _MoodChartState.initState (package:pro_app/journal/view/mood_chart.dart:58:5)
E/flutter (27721): #4 StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:3846:58)
E/flutter (27721): #5 ComponentElement.mount (package:flutter/src/widgets/framework.dart:3711:5)
E/flutter (27721): #6 Element.inflateWidget (package:flutter/src/widgets/framework.dart:2956:14)
E/flutter (27721): #7 Element.updateChild (package:flutter/src/widgets/framework.dart:2759:12)
E/flutter (27721): #8 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #9 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #10 StatelessElement.update (package:flutter/src/widgets/framework.dart:3796:5)
E/flutter (27721): #11 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #12 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #13 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #14 ProxyElement.update (package:flutter/src/widgets/framework.dart:4006:5)
E/flutter (27721): #15 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #16 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #17 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #18 ProxyElement.update (package:flutter/src/widgets/framework.dart:4006:5)
E/flutter (27721): #19 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #20 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4601:32)
E/flutter (27721): #21 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4992:17)
E/flutter (27721): #22 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #23 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #24 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #25 StatefulElement.update (package:flutter/src/widgets/framework.dart:3894:5)
E/flutter (27721): #26 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #27 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #28 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #29 ProxyElement.update (package:flutter/src/widgets/framework.dart:4006:5)
E/flutter (27721): #30 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #31 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #32 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #33 StatefulElement.update (package:flutter/src/widgets/framework.dart:3894:5)
E/flutter (27721): #34 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #35 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4883:14)
E/flutter (27721): #36 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #37 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #38 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #39 StatelessElement.update (package:flutter/src/widgets/framework.dart:3796:5)
E/flutter (27721): #40 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #41 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4883:14)
E/flutter (27721): #42 Element.updateChild (package:flutter/src/widgets/framework.dart:2748:15)
E/flutter (27721): #43 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3747:16)
E/flutter (27721): #44 Element.rebuild (package:flutter/src/widgets/framework.dart:3559:5)
E/flutter (27721): #45 StatefulElement.update (package:flutter/src/widgets/framework.dart:3894:5)
E/flutter (27721): #46 Element.updateChild (package:flutter/src/wid
Mood Model file
import 'package:flutter/material.dart';
class Mood {
int _moodID;
int _emojiID;
int _actID;
int _moodDay;
int _moodMonth;
int _moodYear;
Mood(this._emojiID, this._moodDay, this._moodMonth, this._moodYear,
this._actID);
Mood.withId(this._moodID, this._emojiID, this._moodDay, this._moodMonth,
this._moodYear, this._actID);
int get moodID => _moodID;
int get emojiID => _emojiID;
int get actID => _actID;
int get moodDay => _moodDay;
int get moodMonth => _moodMonth;
int get moodYear => _moodYear;
// can define setters as well
Map<String, int> toMap() {
var map = Map<String, int>();
if (_moodID != null) {
map['moodId'] = _moodID;
}
map['emojiId'] = _emojiID;
map['actId'] = _actID;
map['moodDay'] = _moodDay;
map['moodMonth'] = _moodMonth;
map['moodYear'] = _moodYear;
return map;
}
Mood.fromMap(Map<String, int> map) {
this._moodID = map['moodId'];
this._emojiID = map['emojiId'];
this._actID = map['actId'];
this._moodDay = map['moodMap'];
this._moodMonth = map['moodMonth'];
this._moodYear = map['moodYear'];
}
}
*Database file
import 'package:path/path.dart';
import 'dart:async';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'dart:io';
import '../models/mood_model.dart';
class DatabaseHelper {
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
final String tableName = "moodTable";
final String colMoodId = "moodId";
final String colEmojiId = "emojiId";
final String colActId = "actId";
final String colMoodDay = "moodDay";
final String colMoodMonth = "moodMonth";
final String colMoodYear = "moodYear";
static Database _db;
Future<Database> get db async {
if (_db == null) {
return initDb();
}
return _db;
}
DatabaseHelper.internal();
Future<Database> initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "mood.db");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return ourDb;
}
void _onCreate(Database db, int version) async {
await db.execute(
"CREATE TABLE moodTable (moodId INTEGER PRIMARY KEY, emojiId INTEGER, actId INTEGER, moodDay INTEGER, moodMonth INTEGER, moodYear INTEGER)");
print("Table Created");
}
// insert
Future<int> saveMood(Mood mood) async {
var dbClient = await this.db;
int result = await dbClient.insert("$tableName", mood.toMap());
print('Saved');
return result;
}
// to get number of mood days
Future<List<Map<String, dynamic>>> listOfMoods() async {
Database db = await this.db;
var result = await db.query(tableName, orderBy: '$colMoodId ASC');
return result;
}
Future<int> numOfMoodDays(int emojiID) async {
Database db = await this.db;
var result = await db.query(tableName,
orderBy: '$colMoodId ASC',
where: '$colEmojiId = ?',
whereArgs: [emojiID]);
return result.length;
}
// close db
Future close() async {
var dbClient = await db;
return dbClient.close();
}
}
Mood_Chart file snippet
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:charts_flutter/flutter.dart' as charts;
import '../view/mood.dart';
import '../models/mood_db.dart';
import 'dart:async';
class Mood {
String _emoji;
int _numOfDays; // this has to int bcz charts can't take future<int>
charts.Color _color;
Mood(this._emoji, this._numOfDays, this._color);
}
class MoodChart extends StatefulWidget {
#override
_MoodChartState createState() => _MoodChartState();
}
class _MoodChartState extends State<MoodChart> {
DatabaseHelper _databaseHelper = DatabaseHelper();
List<Mood> _data;
List<charts.Series<Mood, String>> _chartData;
// Here I used async-await but this function still return Future<int>
numOfDaysFn(int id) async {
int numOfDays =await _databaseHelper.numOfMoodDays(id);
return numOfDays;
}
void initData() async {
_chartData = List<charts.Series<Mood, String>>();
_data = <Mood>[
Mood(
allMoods[0], numOfDaysFn(1), charts.MaterialPalette.red.shadeDefault),
Mood(allMoods[1], numOfDaysFn(2),
charts.MaterialPalette.blue.shadeDefault),
Mood(allMoods[2], numOfDaysFn(3),
charts.MaterialPalette.gray.shadeDefault),
Mood(allMoods[3], numOfDaysFn(4),
charts.MaterialPalette.indigo.shadeDefault),
Mood(allMoods[4], numOfDaysFn(5),
charts.MaterialPalette.green.shadeDefault),
];
_chartData.add(charts.Series(
id: 'Mood',
data: _data,
colorFn: (Mood mood, _) => mood._color,
domainFn: (Mood mood, _) => mood._emoji,
measureFn: (Mood mood, _) => **mood._numOfDays**, //this can't take futures
));
}
#override
void initState() {
super.initState();
initData();
}
#override
Widget build(BuildContext context) {
return Container(
child: charts.PieChart(
_chartData,
animate: true,
),
);
}
}
List allMoods = ['Disgusting', 'Bad', 'Ok', 'Good', 'Amazing'];

I do not know if this code runs because your sample code is not complete.
You kinda need to learn how dart futures work. When you call it, the result will return later like Javascript promises
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:charts_flutter/flutter.dart' as charts;
import '../view/mood.dart';
import '../models/mood_db.dart';
import 'dart:async';
class Mood {
String _emoji;
int _numOfDays; // this has to int bcz charts can't take future<int>
charts.Color _color;
Mood(this._emoji, this._numOfDays, this._color);
}
class MoodChart extends StatefulWidget {
#override
_MoodChartState createState() => _MoodChartState();
}
class _MoodChartState extends State<MoodChart> {
DatabaseHelper _databaseHelper = DatabaseHelper();
List<Mood> _data;
List<charts.Series<Mood, String>> _chartData = null;
// Here I used async-await but this function still return Future<int>
Future<List<int>> numOfDaysFn(List<int> days) async {
return Future.wait(days.map((d) => _databaseHelper.numOfMoodDays(d)));
}
void initData( List<int> idx, List<int> days) {
setState(() {
_chartData = List<charts.Series<Mood, String>>();
_data = <Mood>[
Mood(
allMoods[idx[0]-1], days[0], charts.MaterialPalette.red.shadeDefault),
Mood(allMoods[idx[1]-1], days[1],
charts.MaterialPalette.blue.shadeDefault),
Mood(allMoods[idx[2]-1], days[2],
charts.MaterialPalette.gray.shadeDefault),
Mood(allMoods[idx[3]-1], days[3],
charts.MaterialPalette.indigo.shadeDefault),
Mood(allMoods[idx[4]-1], days[4],
charts.MaterialPalette.green.shadeDefault),
];
_chartData.add(charts.Series(
id: 'Mood',
data: _data,
colorFn: (Mood mood, _) => mood._color,
domainFn: (Mood mood, _) => mood._emoji,
measureFn: (Mood mood, _) => mood._numOfDays, //this can't take futures
));
});
}
#override
void initState() {
super.initState();
var months = [1,2,3,4,5];
numOfDaysFn(months).then((days) {
initData(months, days);
});
}
#override
Widget build(BuildContext context) {
if(_chartData != null ){
return Container(
child: charts.PieChart(
_chartData,
animate: true,
),
);
} else {
return CircularProgressIndicator();
}
}
}
Revision 1
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:charts_flutter/flutter.dart' as charts;
import '../view/mood.dart';
import '../models/mood_db.dart';
import 'dart:async';
class Mood {
String _emoji;
int _numOfDays; // this has to int bcz charts can't take future<int>
charts.Color _color;
Mood(this._emoji, this._numOfDays, this._color);
}
class MoodChart extends StatefulWidget {
#override
_MoodChartState createState() => _MoodChartState();
}
class _MoodChartState extends State<MoodChart> {
DatabaseHelper _databaseHelper = DatabaseHelper();
List<Mood> _data;
List<charts.Series<Mood, String>> _chartData = null;
static List<charts.Color> DEFAULT_SHADE = [
null,
charts.MaterialPalette.red.shadeDefault,
charts.MaterialPalette.blue.shadeDefault,
charts.MaterialPalette.gray.shadeDefault,
charts.MaterialPalette.indigo.shadeDefault,
charts.MaterialPalette.green.shadeDefault];
Future<Mood> numOfDaysFn(int day) async {
return Mood( allMood[day-1] , _databaseHelper.numOfMoodDays(day), DEFAULT_SHADE[day] );
}
Future<List<Mood>> returnAllNumOfDaysFn( List<int> days) async {
return Future.wait(days.map((d) => numOfDaysFn(d)));
}
#override
void initState() {
super.initState();
var months = [1,2,3,4,5];
returnAllNumOfDaysFn(months).then((moods) {
var temp = charts.Series(
id: 'Mood',
data: _data,
colorFn: (Mood mood, _) => mood._color,
domainFn: (Mood mood, _) => mood._emoji,
measureFn: (Mood mood, _) => mood._numOfDays, //this can't take futures
);
setState(() {
_data = moods;
_chartData = temp;
});
});
}
#override
Widget build(BuildContext context) {
if(_chartData != null ){
return Container(
child: charts.PieChart(
_chartData,
animate: true,
),
);
} else {
return CircularProgressIndicator();
}
}
}
https://www.dartlang.org/guides/libraries/futures-error-handling
https://docs.flutter.io/flutter/widgets/State/initState.html
https://www.dartlang.org/tutorials/language/futures#calling-multiple-funcs
Edit: you need to understand setState too
https://docs.flutter.io/flutter/widgets/State/setState.html
Flutter charts provide sample with static data. However, you are fetching data dynamically so you need to call set state.

Related

Flutter: How do i stop rendering "Widget build()" unnecessarily again and again?

This is a small POC in Flutter, where my build() function is being called again and again.
This was not expected at all without any loops and after a lot of research, I am calling "Future" in initState() as well.
But still facing the same issue.
Thank you in advance for time!
What have I tried..
import 'package:flutter/material.dart';
//http_request
import 'package:http/http.dart' as http; //to handle the http request
// import 'dart:async'; // for async functions
import 'dart:async' show Future;
import 'dart:convert'; //to convert the http response in JSON formate
import 'HomePage.dart';
class Reports extends StatefulWidget {
#override
_Reports createState() => _Reports();
}
class _Reports extends State<Reports> {
static String url = "Some Url";
String _response = "abc";
#override
void initState() {
super.initState();
getTradeName_dropdown_ITR_Computation_DATA();
}
#override
Widget build(BuildContext context) {
print('body');
return Scaffold(
body: Container(
child: new Text(_response),
),
);
}
Future getTradeName_dropdown_ITR_Computation_DATA() async {
try {
http.Response response =
await http.get("http://" + url );
if (this.mounted) {
setState(() {
String jsonTradeName_dropdown = response.body;
_response = jsonTradeName_dropdown;
});
}
} on Exception {
setState(() {
_response = "Some error occored. Please Try again...";
});
}
}
}
output:
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
I/flutter ( 5760): body
You were making couple of mistakes, here is the correct code. You should use a String instead of a Text widget to show the response.
class _Reports extends State<Reports> {
static String url = "url";
String _response = "abc";
#override
void initState() {
super.initState();
getTradeName_dropdown_ITR_Computation_DATA();
}
#override
Widget build(BuildContext context) {
print('body');
return Scaffold(
body: Container(
child: new Text(_response),
),
);
}
Future getTradeName_dropdown_ITR_Computation_DATA() async {
try {
http.Response response =
await http.get("url_goes_here");
if (this.mounted) {
setState(() {
String jsonTradeName_dropdown = response.body;
_response = jsonTradeName_dropdown;
});
}
} on Exception {
setState(() {
_response = "Some error occored. Please Try again...";
});
}
}
}
The proper model for understanding build() is that you should imagine it is being called sixty times a second. So your build() routine should be fast and idempotent.
In practice, there are optimizations made by the framework so that it isn't called except when needed, but you shouldn't view excessive calls to build() as a failure.

type '_BuiltList<Data>' is not a subtype of type 'List<Data>'

I have a response something like following
{
"status": 1,
"msg": "Success",
"data": [
{
"student_id": "1",
"stud_name": "Aashr ",
"stud_profilepic": "http://default/default.png",
"student_email": "a.su.com",
"student_mobile": "9819",
"course_name": "Busieurship",
"class_code": "ISM-A",
"year_name": "2020",
"disciplineId": "1",
"schoolId": "2",
"minAvg": 30,
"avg": 55
},
{
"student_id": "2",
"stud_name": "Aas ",
"stud_profilepic": "http:lt/default.png",
"student_email": "aasl.com",
"student_mobile": "975",
"course_name": "Businurship",
"class_code": "ISM-B",
"year_name": "2020",
"disciplineId": "1",
"schoolId": "2",
"minAvg": 30,
"avg": 19
}....
I am following this sample
https://github.com/ReactiveX/rxdart/tree/master/example/flutter/github_search
When I convert my json to Dart
class StudentModel {
int status;
String msg;
List<Data> data;
StudentModel({this.status, this.msg, this.data});
StudentModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
msg = json['msg'];
if (json['data'] != null) {
data = new List<Data>();
json['data'].forEach((v) {
data.add(new Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['status'] = this.status;
data['msg'] = this.msg;
if (this.data != null) {
data['data'] = this.data.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
String studentId;
String studName;
String studProfilepic;
String studentEmail;
String studentMobile;
String courseName;
String classCode;
String yearName;
String disciplineId;
String schoolId;
int minAvg;
int avg;
Data(
{this.studentId,
this.studName,
this.studProfilepic,
this.studentEmail,
this.studentMobile,
this.courseName,
this.classCode,
this.yearName,
this.disciplineId,
this.schoolId,
this.minAvg,
this.avg});
Data.fromJson(Map<String, dynamic> json) {
studentId = json['student_id'];
studName = json['stud_name'];
studProfilepic = json['stud_profilepic'];
studentEmail = json['student_email'];
studentMobile = json['student_mobile'];
courseName = json['course_name'];
classCode = json['class_code'];
yearName = json['year_name'];
disciplineId = json['disciplineId'];
schoolId = json['schoolId'];
minAvg = json['minAvg'];
avg = json['avg'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['student_id'] = this.studentId;
data['stud_name'] = this.studName;
data['stud_profilepic'] = this.studProfilepic;
data['student_email'] = this.studentEmail;
data['student_mobile'] = this.studentMobile;
data['course_name'] = this.courseName;
data['class_code'] = this.classCode;
data['year_name'] = this.yearName;
data['disciplineId'] = this.disciplineId;
data['schoolId'] = this.schoolId;
data['minAvg'] = this.minAvg;
data['avg'] = this.avg;
return data;
}
}
And I use in my code everything works fine but suppose I use built value instead of converting json to Dart
library student_model;
import 'dart:convert';
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
import 'package:search/models/serializers.dart';
part 'student_model.g.dart';
abstract class StudentModel implements Built<StudentModel, StudentModelBuilder> {
StudentModel._();
factory StudentModel([updates(StudentModelBuilder b)]) = _$StudentModel;
#nullable
#BuiltValueField(wireName: 'status')
int get status;
#nullable
#BuiltValueField(wireName: 'msg')
String get msg;
#nullable
#BuiltValueField(wireName: 'data')
BuiltList<Data> get data;
String toJson() {
return json.encode(serializers.serializeWith(StudentModel.serializer, this));
}
static StudentModel fromJson(String jsonString) {
return serializers.deserializeWith(
StudentModel.serializer, json.decode(jsonString));
}
static Serializer<StudentModel> get serializer => _$studentModelSerializer;
}
abstract class Data implements Built<Data, DataBuilder> {
Data._();
factory Data([updates(DataBuilder b)]) = _$Data;
#nullable
#BuiltValueField(wireName: 'student_id')
String get studentId;
#nullable
#BuiltValueField(wireName: 'stud_name')
String get studName;
#nullable
#BuiltValueField(wireName: 'stud_profilepic')
String get studProfilepic;
#nullable
#BuiltValueField(wireName: 'student_email')
String get studentEmail;
#nullable
#BuiltValueField(wireName: 'student_mobile')
String get studentMobile;
#nullable
#BuiltValueField(wireName: 'course_name')
String get courseName;
#nullable
#BuiltValueField(wireName: 'class_code')
String get classCode;
#nullable
#BuiltValueField(wireName: 'year_name')
String get yearName;
#nullable
#BuiltValueField(wireName: 'disciplineId')
String get disciplineId;
#nullable
#BuiltValueField(wireName: 'schoolId')
String get schoolId;
#nullable
#BuiltValueField(wireName: 'minAvg')
int get minAvg;
#nullable
#BuiltValueField(wireName: 'avg')
int get avg;
String toJson() {
return json.encode(serializers.serializeWith(Data.serializer, this));
}
static Data fromJson(String jsonString) {
return serializers.deserializeWith(
Data.serializer, json.decode(jsonString));
}
static Serializer<Data> get serializer => _$dataSerializer;
}
I get following error in my code
The following assertion was thrown building StreamBuilder<SearchState>(dirty, state:
I/flutter ( 3684): _StreamBuilderBaseState<SearchState, AsyncSnapshot<SearchState>>#a0ef6):
I/flutter ( 3684): type '_BuiltList<Data>' is not a subtype of type 'List<Data>'
I/flutter ( 3684): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter ( 3684): more information in this error message to help you determine and fix the underlying cause.
I/flutter ( 3684): In either case, please report this assertion by filing a bug on GitHub:
I/flutter ( 3684): https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter ( 3684): When the exception was thrown, this was the stack:
I/flutter ( 3684): #0 SearchScreenState.build.<anonymous closure> (package:search/screens/search_widget.dart:88:54)
I/flutter ( 3684): #1 StreamBuilder.build (package:flutter/src/widgets/async.dart:423:74)
I/flutter ( 3684): #2 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:125:48)
I/flutter ( 3684): #3 StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
I/flutter ( 3684): #4 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
I/flutter ( 3684): #5 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter ( 3684): #6 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33)
I/flutter ( 3684): #7 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:676:20)
I/flutter ( 3684): #8 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
I/flutter ( 3684): #9 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter ( 3684): #10 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter ( 3684): #11 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
I/flutter ( 3684): #12 _invoke (dart:ui/hooks.dart:154:13)
I/flutter ( 3684): #13 _drawFrame (dart:ui/hooks.dart:143:3)
Here is my request code
Future<StudentModel> fetchStudents(String disciplineId, String schoolId,
String year_id, String keyword) async {
final response = await http.post(GET_STUDENTS, body: {
"disciplineId": disciplineId,
"schoolId": schoolId,
"year_id": year_id,
"keyword": keyword
});
print("response2 is ${response.body.toString()}");
StudentModel studentModel = standardSerializers.deserializeWith(StudentModel.serializer, jsonDecode(response.body));
print("response is ${studentModel.toString()}");
return studentModel;
}
I also tried replacing the standardSerializers with normal serializers like following but it gives error
StudentModel studentModel = serializers.deserializeWith(StudentModel.serializer, jsonDecode(response.body));
Why this is a problem with built value and not with normal json to Dart conversion?
BuiltList<Data> is not a List<Data>. If you want to pass a BuiltList where a List is expected you need to use .toList()
For example in this line
I/flutter ( 3684): #0 SearchScreenState.build.<anonymous closure> (package:search/screens/search_widget.dart:88:54)
Instead of data use data.toList()
or change the receiver so that it accepts a BuiltList<Data> instead of a List<Data>

type 'Future<dynamic>' is not a subtype of type 'Future<int>' exception in flutter database creation

I am new in flutter application development. In my flutter application, I create a database using path provider plugin and SQFLite. But it is not working, it shows an exception message
type 'Future' is not a subtype of type 'Future'
I add my code here
static final DatabaseHelper _instance = new DatabaseHelper.internal();
factory DatabaseHelper() => _instance;
static Database _db;
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDb();
return _db;
}
DatabaseHelper.internal();
initDb() async {
Directory documentDirectory = await getApplicationDocumentsDirectory();
String path = join(documentDirectory.path, "tododatabase.db");
var ourDb = await openDatabase(path, version: 1, onCreate: _onCreate);
return ourDb;
}
Future _onCreate(Database db, int version) async {
await db.execute(
"CREATE TABLE TodoList(id INTEGER PRIMARY KEY, todoText TEXT)");
// print("Table is created");
}
//insertion
Future<int> saveTodo(Todo todo) async {
var dbClient = await db;
int res = await dbClient.insert(" TodoList", todo.toMap());
return res;
}
please help me. give a suggestion, please. Thanks in advance.
0631/com.stunntech.fluttertodoapp E/flutter: [ERROR:topaz/lib/tonic/logging/dart_error.cc(16)] Unhandled exception:
type '(Database, int) => void' is not a subtype of type '(Database, int) => Future<dynamic>'
#0 DatabaseHelper.initDb (package:flutter_todo_app/database/database.dart:29:64)
<asynchronous suspension>
#1 DatabaseHelper.db (package:flutter_todo_app/database/database.dart:20:17)
<asynchronous suspension>
#2 DatabaseHelper.saveTodo (package:flutter_todo_app/database/database.dart:40:26)
<asynchronous suspension>
#3 _MyTodoListState._submitTodo (package:flutter_todo_app/todo_list.dart:144:30)
<asynchronous suspension>
#4 _MyTodoListState._showAlert.<anonymous closure> (package:flutter_todo_app/todo_list.dart:97:19)
#5 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:102:24)
#6 TapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:161:9)
#7 TapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:94:7)
#8 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:315:9)
#9 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:73:12)
#10 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:11)
#11 _WidgetsFlutterBinding&BindingBase&GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:143:19)
#12 _WidgetsFlutterBinding&BindingBase&GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:121:22)
#13 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:101:7)
#14 _WidgetsFlutterBinding&BindingBase&GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:64:7)
#15 _WidgetsFlutterBinding&BindingBase&GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:48:7)
#16 _invoke1 (dart:ui/hooks.dart:134:13)
#17 _dispatchPointerDataPacket (dart:ui/hooks.dart:91:5)enter code here
this is the log i get.
You need to have a Future that returns type database for your initDB() method:
Future<Database> initDB() async {
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, "event.db");
var theDatabase = await openDatabase(path, version: 1, onCreate: _onCreate);
return theDatabase;
}
A complete example is here:
https://github.com/dazza5000/austin-feeds-me-flutter/blob/master/lib/data/event_database.dart
class EventsDatabase {
static const EVENT_TABLE_NAME = "event";
static final EventsDatabase _instance = EventsDatabase._internal();
factory EventsDatabase() => _instance;
static Database _db;
Future<Database> get db async {
if (_db != null) {
return _db;
}
_db = await initDB();
return _db;
}
EventsDatabase._internal();
Future<Database> initDB() async {
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, "event.db");
var theDatabase = await openDatabase(path, version: 1, onCreate: _onCreate);
return theDatabase;
}
void _onCreate(Database db, int version) async {
await db.execute("CREATE TABLE " + EVENT_TABLE_NAME + " ("
"id STRING PRIMARY KEY, "
"name TEXT, "
"time INTEGER, "
"description TEXT, "
"url TEXT, "
"photo TEXT, "
"lat DOUBLE, "
"lng DOUBLE)");
}
Future closeDb() async {
var dbClient = await db;
return dbClient.close();
}
}
Your onCreate() function should be of type void (instead of Future) and should be async!

Future Builder to make Sliver Lists

I am trying to generate a dynamic list of slivers from a GET request. But I am having trouble, it seems the response data is null. Here is my code:
import 'package:flutter/material.dart';
import 'boardSummary.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:flutter/foundation.dart';
class HomepageBody extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return HomepageBodyState();
}
}
class HomepageBodyState extends State <HomepageBody> {
#override
Widget build(BuildContext context) {
return new Expanded(
child: new Container(
color: new Color(0xFF736AB7),
child: new FutureBuilder <List<Post>>(
future: fetchPost(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) print(snapshot.error);
else
return jobscroll(context, snapshot);
//: Center(child: CircularProgressIndicator());
}
),
),
);
}
}
Future<List<Post>>fetchPost() async {
final response = await http.get('https://jsonplaceholder.typicode.com/posts?userId=1');
return compute(parsePosts, response.body);
}
List<Post> parsePosts(String responseBody){
final parsed = json.decode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Post>((json)=>Post.fromJson(json)).toList();
}
class Post {
final String userId;
final String hashtag;
final String price;
final String description;
Post({this.userId, this.hashtag, this.price, this.description});
factory Post.fromJson(Map<String, dynamic> json) {
return Post(
userId: json['userId'],
hashtag: json['id'],
price: json['title'],
description: json['body'],
);
}
}
Widget jobscroll(BuildContext context, AsyncSnapshot snapshot) {
List data = snapshot.data;
return CustomScrollView(
scrollDirection: Axis.vertical,
shrinkWrap: false,
slivers: <Widget>[new SliverPadding(
padding: const EdgeInsets.symmetric(vertical: 24.0),
sliver: new SliverList(
delegate: new SliverChildBuilderDelegate(
(context, index) => new BoardSummary(data[index]),
childCount: data.length,
),
),
),
],
);
}
BoardSummary is a stateless widget class that just takes creates a "card" using the properties on each "Post". It takes in a object of type "Post."
The console spit out a lot of errors but this was the last one that seemed meaningful it also appeared in my emulator:
I/flutter (18882): Another exception was thrown: NoSuchMethodError: The getter 'length' was called on null.
EDIT Here's also the first few lines from my slack trace:
E/flutter (13964): type 'int' is not a subtype of type 'String'
E/flutter (13964): #0 new Post.fromJson (file:///home/daniel/Desktop/testapp/lib/ui/homePageBody.dart:76:19)
E/flutter (13964): #1 parsePosts.<anonymous closure> (file:///home/daniel/Desktop/testapp/lib/ui/homePageBody.dart:60:40)
E/flutter (13964): #2 MappedListIterable.elementAt (dart:_internal/iterable.dart:414:29)
E/flutter (13964): #3 ListIterable.toList (dart:_internal/iterable.dart:219:19)
E/flutter (13964): #4 parsePosts (file:///home/daniel/Desktop/testapp/lib/ui/homePageBody.dart:60:56)
E/flutter (13964): #5 _IsolateConfiguration.apply (package:flutter/src/foundation/isolates.dart:88:16)
E/flutter (13964): #6 _spawn.<anonymous closure> (package:flutter/src/foundation/isolates.dart:96:30)
What should I do?
Edit casting this piece of code to string made it work, just have overflow to fix. If there is a better solution feel free to share!
return Post(
userId: json['userId'].toString(),
hashtag: json['id'].toString(),
price: json['title'].toString(),
description: json['body'].toString(),
);
FutureBuilder builds immediately even when the value is not yet available, because build() is sync and can't be delayed.
The FutureBuilder example shows how to check if the value is already available (default: ... and not snapshot.hasError):
new FutureBuilder<String>(
future: _calculation, // a Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none: return new Text('Press button to start');
case ConnectionState.waiting: return new Text('Awaiting result...');
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return new Text('Result: ${snapshot.data}');
}
},
)

Display Firebase database list with Angular Dart

Here is an image for list of firebase data, I am trying to display in my angularDart project with the help of following two articles
1)https://qiita.com/tatsu/items/91bf9b01fd3e5d55cd09
2)https://dart.academy/build-a-real-time-chat-web-app-with-dart-angular-2-and-firebase-3/
but it's getting difficult for me to understand and get the expected result.
So, kindly help me to know where and what I am doing wrong.
error
(anonymous function) Uncaught Unhandled exception:
EXCEPTION: Error in :0:0
ORIGINAL EXCEPTION: NoSuchMethodError: The method 'ref' was called on null.
Receiver: null
Tried calling: ref("names")
ORIGINAL STACKTRACE:
#0 Object._noSuchMethod (dart:core-patch/object_patch.dart:43)
#1 Object.noSuchMethod (dart:core-patch/object_patch.dart:47)
#2 new DatabaseService (package:AngularDart_Firebase_Demo/service/database_service.dart:22:34)
#3 _ViewAppComponentHost0.build (package:AngularDart_Firebase_Demo/app_component.template.dart:465:32)
#4 AppView.createHostView (package:angular/src/core/linker/app_view.dart:233:12)
#5 DebugAppView.createHostView (package:angular/src/debug/debug_app_view.dart:89:34)
#6 ComponentFactory.create (package:angular/src/core/linker/component_factory.dart:77:21)
#7 ApplicationRefImpl.bootstrap.<anonymous closure> (package:angular/src/core/application_ref.dart:348:38)
#8 ApplicationRefImpl.run.<anonymous closure> (package:angular/src/core/application_ref.dart:319:26)
#9 _rootRun (dart:async/zone.dart:1116)
#10 _ZoneDelegate.run (dart:async/zone.dart:675)
#11 NgZone._run (package:angular/src/core/zone/ng_zone.dart:175:21)
#12 _CustomZone.run (dart:async/zone.dart:1001)
#13 NgZone.run (package:angular/src/core/zone/ng_zone.dart:304:23)
#14 ApplicationRefImpl.run (package:angular/src/core/application_ref.dart:317:10)
#15 ApplicationRefImpl.bootstrap (package:angular/src/core/application_ref.dart:346:12)
#16 coreLoadAndBootstrap.<anonymous closure> (package:angular/src/core/application_ref.dart:92:19)
<asynchronous suspension>
#17 ApplicationRefImpl.run.<anonymous closure> (package:angular/src/core/application_ref.dart:319:26)
#18 _rootRun (dart:async/zone.dart:1120)
#19 _ZoneDelegate.run (dart:async/zone.dart:675)
#20 NgZone._run (package:angular/src/core/zone/ng_zone.dart:175:21)
#21 _CustomZone.run (dart:async/zone.dart:1001)
#22 NgZone.run (package:angular/src/core/zone/ng_zone.dart:304:23)
#23 ApplicationRefImpl.run (package:angular/src/core/application_ref.dart:317:10)
#24 coreLoadAndBootstrap (package:angular/src/core/application_ref.dart:87:23)
<asynchronous suspension>
#25 bootstrapStatic (package:angular/src/platform/bootstrap.dart:129:10)
#26 main (http://localhost:59274/main.dart:9:3)
ERROR CONTEXT:
Instance of 'DebugContext'
#0 DebugAppView._rethrowWithContext (package:angular/src/debug/debug_app_view.dart:319:9)
#1 DebugAppView.createHostView (package:angular/src/debug/debug_app_view.dart:91:12)
#2 ComponentFactory.create (package:angular/src/core/linker/component_factory.dart:77:21)
#3 ApplicationRefImpl.bootstrap.<anonymous closure> (package:angular/src/core/application_ref.dart:348:38)
#4 ApplicationRefImpl.run.<anonymous closure> (package:angular/src/core/application_ref.dart:319:26)
#5 _rootRun (dart:async/zone.dart:1116)
#6 _ZoneDelegate.run (dart:async/zone.dart:675)
#7 NgZone._run (package:angular/src/core/zone/ng_zone.dart:175:21)
#8 _CustomZone.run (dart:async/zone.dart:1001)
#9 NgZone.run (package:angular/src/core/zone/ng_zone.dart:304:23)
#10 ApplicationRefImpl.run (package:angular/src/core/application_ref.dart:317:10)
#11 ApplicationRefImpl.bootstrap (package:angular/src/core/application_ref.dart:346:12)
#12 coreLoadAndBootstrap.<anonymous closure> (package:angular/src/core/application_ref.dart:92:19)
<asynchronous suspension>
#13 ApplicationRefImpl.run.<anonymous closure> (package:angular/src/core/application_ref.dart:319:26)
#14 _rootRun (dart:async/zone.dart:1120)
#15 _ZoneDelegate.run (dart:async/zone.dart:675)
#16 NgZone._run (package:angular/src/core/zone/ng_zone.dart:175:21)
#17 _CustomZone.run (dart:async/zone.dart:1001)
#18 NgZone.run (package:angular/src/core/zone/ng_zone.dart:304:23)
#19 ApplicationRefImpl.run (package:angular/src/core/application_ref.dart:317:10)
#20 coreLoadAndBootstrap (package:angular/src/core/application_ref.dart:87:23)
<asynchronous suspension>
#21 bootstrapStatic (package:angular/src/platform/bootstrap.dart:129:10)
#22 main (http://localhost:59274/main.dart:9:3)
database_service.dart
import 'dart:async';
import 'dart:math';
import 'package:AngularDart_Firebase_Demo/src/name.dart';
import 'package:angular/angular.dart';
import 'package:firebase/firebase.dart' as fb;
#Injectable()
class DatabaseService {
fb.Database _fbDatabase;
fb.DatabaseReference _fbDatabaseRef;
final List<Name> names = [];
int _maxId = 0;
DatabaseService() {
fb.initializeApp(
apiKey: "AIzaSyBQ3GFAEHOLUNS72C4Sii4iZbRcag6o9ZZ",
authDomain: "angulardart-firebase-demo.firebaseapp.com",
databaseURL: "https://angulardart-firebase-demo.firebaseio.com",
storageBucket: "angulardart-firebase-demo.appspot.com",
);
_fbDatabaseRef = _fbDatabase.ref("names");
try {
// Listening for updates
_fbDatabaseRef.onChildAdded.listen((e) {
Name name = new Name.fromJson(e.snapshot.val());
_maxId = max(name.id, _maxId);
names.add(name);
});
_fbDatabaseRef.onChildRemoved.listen((e) {
Name name = new Name.fromJson(e.snapshot.val());
names.remove(names.firstWhere((h) => h.id == name.id));
});
_fbDatabaseRef.onChildChanged.listen((e) {
Name name = new Name.fromJson(e.snapshot.val());
names
.firstWhere((h) => h.id == name.id)
.title = name.title;
});
} catch (e) {
throw _handleError(e);
}
}
Future<Name> getHero(int id) async {
// It's possible the _heroes is not ready on the page load.
final name = names.firstWhere((name) => name.id == id, orElse: () => null);
if (name != null) {
return new Future.value(name);
} else {
// Try to fetch him from Firebase.
// It might not the best design, while Firebase can be expected to handle a cached hero data effectively.
// Should be added index on id later.
final queryEvent = await _fbDatabaseRef.orderByChild('id').equalTo(id).once('value');
final snapshot = queryEvent.snapshot.val();
return new Name.fromJson(snapshot.values.first);
}
}
Future<Name> update(Name name) async {
try {
var e = await _fbDatabaseRef.orderByChild('id').equalTo(name.id).once('value');
e.snapshot.forEach((child) {
child.ref.update(name.toJson());
});
return name;
} catch (e) {
throw _handleError(e);
}
}
Future<Null> delete(int id) async {
try {
var e = await _fbDatabaseRef.orderByChild('id').equalTo(id).once('value');
e.snapshot.forEach((child) {
child.ref.remove();
});
} catch (e) {
throw _handleError(e);
}
}
Exception _handleError(dynamic e) {
print(e); // for demo purposes only
return new Exception('Server error; cause: $e');
}
}
app_component.dart
import 'package:AngularDart_Firebase_Demo/service/database_service.dart';
import 'package:angular/angular.dart';
import 'package:angular_components/angular_components.dart';
#Component(
selector: 'my-app',
styleUrls: const ['app_component.css'],
templateUrl: 'app_component.html',
directives: const [
CORE_DIRECTIVES,
materialDirectives,
],
providers: const [
materialProviders,
DatabaseService,
],
)
class AppComponent {
final title = 'List of names!';
final DatabaseService dbService;
AppComponent(DatabaseService this.dbService);
}
name.dart
class Name {
final int id;
String title;
Name(this.id, this.title);
factory Name.fromJson(Map<String, dynamic> name) =>
new Name(_toInt(name['id']), name['name']);
Map toJson() => {'id': id, 'title': title};
}
int _toInt(id) => id is int ? id : int.parse(id);
app_component.html
<h1>{{title}}</h1>
<h2>List of names</h2>
<material-list>
<material-list-item class="names"
*ngFor="let name of dbService.names"
[class.selected]="name === selectedName"
(trigger)="onSelect(name)">
<div>{{name.id}}</div>
<div>{{name.title}}</div>
</material-list-item>
</material-list>
after initializing the database _fbDatabase = fb.database(); it worked, but still only the id's are displaying title is not been displayed.
database_service.dart
import 'dart:async';
import 'dart:math';
import 'package:AngularDart_Firebase_Demo/src/name.dart';
import 'package:angular/angular.dart';
import 'package:firebase/firebase.dart' as fb;
#Injectable()
class DatabaseService {
fb.Database _fbDatabase;
fb.DatabaseReference _fbDatabaseRef;
final List<Name> names = [];
int _maxId = 0;
DatabaseService() {
fb.initializeApp(
apiKey: "AIzaSyBQ3GFAEHOLUNS72C4Sii4iZbRcag6o6iY",
authDomain: "angulardart-firebase-demo.firebaseapp.com",
databaseURL: "https://angulardart-firebase-demo.firebaseio.com",
storageBucket: "angulardart-firebase-demo.appspot.com",
);
_fbDatabase = fb.database();
_fbDatabaseRef = _fbDatabase.ref("names");
try {
// Listening for updates
_fbDatabaseRef.onChildAdded.listen((e) {
Name name = new Name.fromJson(e.snapshot.val());
_maxId = max(name.id, _maxId);
names.add(name);
});
_fbDatabaseRef.onChildRemoved.listen((e) {
Name name = new Name.fromJson(e.snapshot.val());
names.remove(names.firstWhere((h) => h.id == name.id));
});
_fbDatabaseRef.onChildChanged.listen((e) {
Name name = new Name.fromJson(e.snapshot.val());
names
.firstWhere((h) => h.id == name.id)
.title = name.title;
});
} catch (e) {
throw _handleError(e);
}
}
Future<Name> getHero(int id) async {
// It's possible the _heroes is not ready on the page load.
final name = names.firstWhere((name) => name.id == id, orElse: () => null);
if (name != null) {
return new Future.value(name);
} else {
// Try to fetch him from Firebase.
// It might not the best design, while Firebase can be expected to handle a cached hero data effectively.
// Should be added index on id later.
final queryEvent = await _fbDatabaseRef.orderByChild('id').equalTo(id).once('value');
final snapshot = queryEvent.snapshot.val();
return new Name.fromJson(snapshot.values.first);
}
}
Future<Name> update(Name name) async {
try {
var e = await _fbDatabaseRef.orderByChild('id').equalTo(name.id).once('value');
e.snapshot.forEach((child) {
child.ref.update(name.toJson());
});
return name;
} catch (e) {
throw _handleError(e);
}
}
Future<Null> delete(int id) async {
try {
var e = await _fbDatabaseRef.orderByChild('id').equalTo(id).once('value');
e.snapshot.forEach((child) {
child.ref.remove();
});
} catch (e) {
throw _handleError(e);
}
}
Exception _handleError(dynamic e) {
print(e); // for demo purposes only
return new Exception('Server error; cause: $e');
}
}
This field is never initialized:
fb.Database _fbDatabase;
Add this line before the above one
_fbDatabaseRef = fb.database();
_fbDatabaseRef = _fbDatabase.ref("names");
See also https://github.com/firebase/firebase-dart/blob/master/example/realtime_database/index.dart

Resources