I am building a chrome extension using Flutter Web, which is just a simple ListView
on the home screen and basic CRUD operations. I am using dart:js
package to call methods from a JS file which performs some operations on the Firebase Realtime Database.
Adding a new entry to the database is working through the add()
method call. Read operation is also working in the JS file just fine.
My main question is how I am supposed to read the database info as JSON, parse it and display it as ListView
in Flutter.
Here goes main.dart
and AddAttendee.dart
-
import 'dart:js' as js;
import 'dart:convert';
import 'package:flutter/material.dart';
import 'AddAttendee.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Google Flutter Meet Attendance',
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<Map> data;
getAttendees() async {
var obj = await js.context.callMethod('read');
List<Map> users = (jsonDecode(obj) as List<dynamic>).cast<Map>();
setState(() {
data = users;
});
}
@override
void initState() {
getAttendees();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Current Attendees"),
),
body: data != null
? ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.person),
title: Text(data.toString()[index]), // I don't know how to read correctly
);
},
)
: Center(child: CircularProgressIndicator()),
floatingActionButton: FloatingActionButton(
tooltip: 'Add to Attendance',
child: Icon(Icons.person_add),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => AddAttendee(),
),
),
),
);
}
}
import 'dart:js' as js;
import 'package:flutter/material.dart';
class AddAttendee extends StatefulWidget {
@override
_AddAttendeeState createState() => _AddAttendeeState();
}
class _AddAttendeeState extends State<AddAttendee> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _textController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Add to Attendance List"),
),
body: Form(
key: _formKey,
child: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
child: TextFormField(
autocorrect: false,
autofocus: true,
controller: _textController,
onFieldSubmitted: (value) => _textController.text = value,
decoration: InputDecoration(labelText: "Name"),
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
textCapitalization: TextCapitalization.sentences,
validator: (value) {
if (value.isEmpty) return 'This field is mandatory';
return null;
},
),
),
),
floatingActionButton: FloatingActionButton(
tooltip: "Done",
child: Icon(Icons.done),
onPressed: () {
if (_formKey.currentState.validate()) {
js.context.callMethod('add', [_textController.text]);
Navigator.pop(context);
}
},
),
);
}
}
Here is the JS code -
const dbRef = firebase.database().ref();
var userList = [];
function read() {
dbRef.once("value", function (snapshot) {
userList = [];
snapshot.forEach(function (childSnapshot) {
var key = childSnapshot.key;
var user = childSnapshot.val();
userList.push({ key, user });
});
});
return userList;
}
function add(user) {
let newUser = { name: user };
dbRef.push(newUser, function () {
console.log("Attendance Record Updated - New Attendee Added");
});
}
Database structure in Firebase RT DB -
Database structure when parsed -
It's just so frustrating debugging this code because I can't print
the outputs of the main.dart
and if any error happens and an exception is thrown then it is displayed in form of transcompiled main.dart.js
file which is impossible to read.
I haven't been able to get the data back from the read()
method in the JS file to main.dart
. How to do that?
Some links for reference -
https://twitter.com/rodydavis/status/1197564669633978368 https://www.reddit.com/r/FlutterDev/comments/dyd8j5/create_chrome_extension_running_flutter/ https://github.com/rodydavis/dart_pad_ext/