I'm returning fetch data from MQTT broker and set the data in a variable. I got this issue, may I know why?
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: true,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: sensor01(),
);
}
}
class sensor01 extends StatefulWidget {
const sensor01({Key? key}) : super(key: key);
@override
State<sensor01> createState() => _sensor01();
}
class _sensor01 extends State<sensor01> {
// connection succeeded
void onConnected() {
print('Connected');
}
// unconnected
void onDisconnected() {
print('Disconnected');
}
// subscribe to topic succeeded
void onSubscribed(String topic) {
print('Subscribed topic: $topic');
}
// subscribe to topic failed
void onSubscribeFail(String topic) {
print('Failed to subscribe $topic');
}
// unsubscribe succeeded
void onUnsubscribed(String topic) {
print('Unsubscribed topic: $topic');
}
// PING response received
void pong() {
print('Ping response client callback invoked');
}
var data;
Future<MqttServerClient> connect() async {
MqttServerClient client = MqttServerClient.withPort(host, id, port);
client.logging(on: false);
client.onConnected = onConnected;
client.onDisconnected = onDisconnected;
// client.onUnsubscribed = onUnsubscribed;
client.onSubscribed = onSubscribed;
client.onSubscribeFail = onSubscribeFail;
client.pongCallback = pong;
client.autoReconnect = false;
final connMessage = MqttConnectMessage()
.authenticateAs(username, password)
.withClientIdentifier(id)
.startClean()
// .withWillRetain()
.withWillQos(MqttQos.atLeastOnce);
client.connectionMessage = connMessage;
try {
await client.connect();
// client.unsubscribe('topic/');
client.subscribe(topic1, MqttQos.atLeastOnce);
} catch (e) {
print('Exception: $e');
client.disconnect();
}
client.updates!.listen((List<MqttReceivedMessage<MqttMessage>> c) {
final MqttPublishMessage message = c[0].payload as MqttPublishMessage;
final payload =
MqttPublishPayload.bytesToStringAsString(message.payload.message);
print('Received message:$payload from topic: ${c[0].topic}>');
Map<String, dynamic> userMap = jsonDecode(payload);
var user = dataList.fromJson(userMap);
setState(() {
if (user.sensorid == 'sensor01') {
data = user.sensorid;
}
});
});
@override
void initState() {
super.initState();
connect();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("MQTT"),
),
body: FutureBuilder(
future: connect(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Center(
child: Text("Error: ${snapshot.error}"),
);
}
// if succeed to connect
if (snapshot.connectionState == ConnectionState.done) {
return ListView(
children: [
Card(
child: ListTile(
title: Text(data),
))
],
padding: EdgeInsets.all(10),
);
}
return Center(child: CircularProgressIndicator());
},
));
}
}
@override
Widget build(BuildContext context) {
// TODO: implement build
throw UnimplementedError();
}
}
I got this one error. The error shows at the Fure function above the override widget. What should I add in order for the code able to run even the returned data is null?
The body might complete normally, causing 'null' to be returned, but the return type, 'FutureOr<MqttServerClient>', is a potentially non-nullable type.
How to solve the error??
CodePudding user response:
In your function connect()
you have the return type of MqttServerClient
:
Future<MqttServerClient> connect() async {}
but you aren't return
ing anything.
your function returns nothing - it's void
.
So, change:
Future<MqttServerClient> connect() async {}
To:
Future<void> connect() async {}