Closed mima1993 closed 4 years ago
You can either hide State
from mongo_dart import:
import 'package:mongo_dart/mongo_dart.dart' hide State;
or assign a prefix to mongo_dart:
import 'package:mongo_dart/mongo_dart.dart' as mongo;
In this last case you will have to prefix all mongo_dart classes with "mongo" (ex. mongo.Db
).
Thanks for help!
I tried but it didn't work, the error occured because in lifetime of [State] widget it call mongo.Db, when running mongo_dart, [State] is ambiguous, unforuntly system treat it as the widget.
My program is list.dart:
import 'package:flutter/material.dart'; import 'package:mongo_dart/mongo_dart.dart' as mongo; import 'package:dio/dio.dart'; import 'detail.dart'; import 'adapt.dart';
Dio dio = Dio();
class TopicList extends StatefulWidget { //固定写法 TopicList({Key key, @required this.tpt}) : super(key: key);
//主题类别 final String tpt;
@override _TopicListState createState() { return _TopicListState(); } }
class _TopicListState extends State
@override bool get wantKeepAlive => true;
//控件被执行的时候会执行initState @override void initState() { super.initState(); getTopicList(); }
@override // ignore: must_call_super Widget build(BuildContext context) { return ListView.builder( itemCount: tplist.length, itemBuilder: (BuildContext ctx, int i) { //当前的主题item项 var tpitem = tplist[i]; return GestureDetector( onTap: () { //跳转到详情 Navigator.push(context, MaterialPageRoute(builder: (BuildContext ctx) { return TopicDetail(id: tpitem['_id'], title: tpitem['title']); })); }, child: Container( height: Adapt.px(200), decoration: BoxDecoration( color: Colors.white, border: Border(top: BorderSide(color: Colors.black12))), child: Row( children: [ Image.network( 'https://i01piccdn.sogoucdn.com/c54a9f0cbafea7a6', width: Adapt.px(130), height: Adapt.px(180), fit: BoxFit.cover, ), Container( padding: EdgeInsets.only( left: Adapt.px(10), ), height: Adapt.px(200), child: DefaultTextStyle( style: TextStyle( fontSize: Adapt.px(16), color: Colors.black87), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Text('标题:${tpitem['title']}'), Text('内容:${tpitem['content']}'), Text('最新:${tpitem['result'].toString()}'), ], ))) ], ), )); }); }
//获取主题列表数据 getTopicList() async { var db = mongo.Db('mongodb://127.0.0.1/hzd'); try { await db.open(); print('Awaiting connecting...'); } catch (err) { print('Caught error: $err'); } var coll = db.collection('topics'); //服务器返回的数据 var result = await coll.find().toList(); //赋值,页面更新 setState(() { tplist.addAll(result); total = result.length; }); } }
If you define it as I told the system will treat it as mongo.State. It must work. Which is exactly the error? The problem should be elsewhere.
The following is an example of a working flutter program. It is a "fast and furious" app (modifying a Stagehand example) that I made in order to test Atlas connections, so please, don't look at the programming style, but look at the logic of the app:
import 'package:flutter/material.dart';
import 'package:mongo_dart/mongo_dart.dart' hide State;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
String atlasUrl = '';
final _biggerFont = const TextStyle(fontSize: 18.0);
final _actions = <String>[];
final _saved = Set<String>();
Widget _buildActions() {
return Expanded(
child: ListView.builder(
padding: const EdgeInsets.all(16.0),
itemCount: _actions.length,
itemBuilder: (context, i) {
return _buildRow(_actions[i]);
},
));
}
Widget _buildRow(String log) {
final alreadySaved = _saved.contains(log);
return ListTile(
title: Text(
log,
style: _biggerFont,
),
trailing: Icon(
alreadySaved ? Icons.favorite : Icons.favorite_border,
color: alreadySaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (alreadySaved) {
_saved.remove(log);
} else {
_saved.add(log);
}
});
},
);
}
// #enddocregion _buildRow
void _connect() async {
print('Urls is: $atlasUrl');
_actions.clear();
_saved.clear();
try {
var db = await Db.create(atlasUrl);
_actions.add('Db created!');
await db.open();
_actions.add('Connected!');
var coll = db.collection('flutter-test');
var result = await coll.insertOne({'flutter': true});
if (result['ok'] == 1.0) {
_actions.add('Inserted!');
} else {
_actions.add(result['errmsg']);
}
} catch (e) {
_actions.add('$e');
} finally {
setState(() {
_counter++;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Atlas Url',
),
onSubmitted: (String value) async {
atlasUrl = value;
}),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
if (_actions.isNotEmpty) _buildActions()
],
),
floatingActionButton: RaisedButton(
onPressed: _connect,
//tooltip: 'Increment',
child: Text("Connect") //Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
Thanks for reply. I tried your program and entered local Mongo database URI, I got the same error: I/flutter (16657): MongoDB ConnectionException: Could not connect to the Data Base. I think Mongodb in my PC is okay because I can add data using program with Mongo_Dart package. If you find a method to resolve the problem, please let me know.
The connection Exception normally occurs when the URL is wrong and/or there is no authentication rights on the database. Eventually try to check the database log for more info
I did some more test, and yes, I couldn't connect on localhost! If I tried to connect to another mongodb instance in my network (let's say 192.168.1.5), no problem, but localhost, it was not working. I guess that the problem is exactly that, inside the emulator the address 127.0.0.1 is the emulator itself! So, I tried the following workaround:
--bind_ip 127.0.0.1,<local_host_ip_address>
. Example --bind_ip 127.0.0.1,192.168.1.10
mongodb://192.168.1.10:27017/test
This way it works!
So, resuming, it seems that the emulator consider localhost as itself and not as the programmer computer. I'm not a flutter expert, so, maybe that there is some setting that could change this behaviour, or maybe that the cause is different, but to me it seems quite a logic consequence of emulating a device.
If anyone else has a better explanation/solution we are waiting for your cents... ;-)Hope that you have solved your problem. I close the issue, feel free to reopen if needed.
The name 'State' is defined in the libraries 'package:flutter/src/widgets/framework.dart' and 'package:mongo_dart/mongo_dart.dart'. The only way to resolve this problem is to change classname 'State' in mongo_dart.dart. Otherwise the following error always exists: I/flutter (11323): Caught error: MongoDB ConnectionException: Could not connect to the Data Base. E/flutter (11323): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: MongoDart Error: Db is in the wrong state: State.OPENING