I'm using new dart version >=2.12.0 <3.0.0 with null safety enabled.
I have added my code for reference.
import 'package:cric_app/AppUrls.dart';
import 'package:cric_app/features/home/match_model.dart';
import 'package:dio/dio.dart';
import 'package:rxdart/rxdart.dart';
class MatchesService {
// ignore: close_sinks
BehaviorSubject<List<MatchModel>> list = BehaviorSubject<List<MatchModel>>();
Future<List<MatchModel>> getMatches() async {
try {
var matchList = await fetchMatches();
list.add(matchList);
return matchList;
} catch (Exc) {
print(Exc);
}
}
Future<List<MatchModel>> fetchMatches() async {
var dio = Dio();
final response = await dio.post(AppUrls.getMatches);
print(response.data);
final body = response.data['matches'] as List;
return body.map((dynamic json) {
return MatchModel(
id: json['id'] as int,
date: json['date'] as String,
dateGmt: json['dateTimeGMT'] as String,
teamOne: json['team-1'] as String,
teamTwo: json['team-2'] as String,
tossWinnerTeam: json['toss_winner_team'] as String,
matchStarted: json['matchStarted'] as bool,
type: json['type'] as String,
winnerTeam: json['winner_team'] as String,
);
}).toList();
}
}
import 'package:cric_app/components/match_card.dart';
import 'package:cric_app/features/home/match_model.dart';
import 'package:cric_app/features/home/matches_service.dart';
import 'package:cric_app/utils.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
MatchesService matchesService = MatchesService();
@override
void initState() {
matchesService.getMatches();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: primary_color,
body: SingleChildScrollView(
child: Container(
margin: setMargin(15, 0, 15, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 30,
),
text('Matches', Colors.white, FontWeight.bold, 23),
SizedBox(
height: 2,
),
text("Today's live matches", Colors.white, FontWeight.bold, 18),
StreamBuilder<List<MatchModel>>(
stream: matchesService.list,
initialData: null,
builder: (context, snapshot) {
if (snapshot.data != null) {
final list = snapshot.data as List;
return ListView.builder(
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return matchCard(context, list[index]);
},
);
} else {
return Center(
child: text(
'No live matches now',
Colors.white,
FontWeight.bold,
16,
),
);
}
},
),
SizedBox(
height: 10,
),
],
),
),
),
);
}
}
I get this error : The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type. Try adding either a return or a throw statement at the end.
In Dart, if your function has no return
statement, that behaves the same as returning null
. For example:
dynamic doesntReturn() {
// do nothing
}
print(doesntReturn()); // prints 'null'
In your case, getMatches()
is an async function that returns a Future<List<MatchModel>>
. However, in your catch
block, you don't return anything, causing an implicit return null
:
Future<List<MatchModel>> getMatches() async {
try {
var matchList = await fetchMatches();
list.add(matchList);
return matchList;
} catch (Exc) {
print(Exc);
}
// "return null" added implicitly
}
However, your function can't return null
, since it has a return type of Future<List<MatchModel>>
. It is complicated a bit by the async-ness, but the following synchronous code has the same behaviour:
List<MatchModel> getMatches() {
try {
return _doSomeCalculation();
} catch (e) {
print(e);
}
}
To fix this, you need to make sure that the implicit return null
is never hit. You can either:
getMatches()
throws: Future<List<MatchModel>> getMatches() async {
try {
var matchList = await fetchMatches();
list.add(matchList);
return matchList;
} catch (Exc) {
print(Exc);
rethrow;
}
getMatches
to return a Future<List<MatchModel>?>
Never
)I'd probably recommend option 1), but it depends on your use case