I have a simple json which I want to display sunrise and sunset times.
My Json looks like this
{
"SunRise" : "5.30:00",
"SunSet" : "6:30:00",
"MoonRise":"19:54:11",
"MoonSet":"7:50:55"
}
My Model Looks like this.
class AutoGenerate {
AutoGenerate({
required this.SunRise,
required this.SunSet,
required this.MoonRise,
required this.MoonSet,
});
late final String SunRise;
late final String SunSet;
late final String MoonRise;
late final String MoonSet;
AutoGenerate.fromJson(Map<String, dynamic> json){
SunRise = json['SunRise'];
SunSet = json['SunSet'];
MoonRise = json['MoonRise'];
MoonSet = json['MoonSet'];
}
Map<String, dynamic> toJson() {
final _data = <String, dynamic>{};
_data['SunRise'] = SunRise;
_data['SunSet'] = SunSet;
_data['MoonRise'] = MoonRise;
_data['MoonSet'] = MoonSet;
return _data;
}
}
MyFetch Mechanism.
Future<AutoGenerate> getData() async {
final response =
await http.get(Uri.parse('MyURL'));
var data = json.decode(response.body);
}
I want to build a set of cards for sun/moon rise/set. Below the mechanism to show how my widget is sent to card.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Container(
alignment: Alignment.center,
child: SafeArea(
child: SingleChildScrollView(
child: FutureBuilder<AutoGenerate>(
future : getData(),
builder: ( context, AsyncSnapshot<AutoGenerate> snapshot)
{
if (snapshot!.hasData) {
return Container(
child : Card(
// margin: EdgeInsets.all(16.0),
elevation: 1.2,
color: Colors.yellowAccent[100],
child: Padding(
padding: EdgeInsets.all(16.0),
child: Text('Sun Rise :' snapshot.data.SunRise),
),
)
)
}
}
)
)
)
)
}
I am getting an error on the snapshot.data.SunRise saying "The property 'SunRise' can't be unconditionally accessed because the receiver can be 'null'. (Documentation) Try making the access conditional (using '?.') or adding a null check to the target ('!').
I have kind of tried all the options and also tried to assign the response to a variable and use that variable to show in the Card but gives me another error.
What is best way to move forward?
Thank you
CodePudding user response:
Add ?.
or !
and if you add !
, you should add after dot(.)
Container(
alignment: Alignment.center,
child: SafeArea(
child: SingleChildScrollView(
child: FutureBuilder<AutoGenerate>(
future: getData(),
builder:
(context, AsyncSnapshot<AutoGenerate> snapshot) {
if (!snapshot.hasData) {
return Container(
child: Card(
// margin: EdgeInsets.all(16.0),
elevation: 1.2,
color: Colors.yellowAccent[100],
child: Padding(
padding: EdgeInsets.all(16.0),
child:
Text("Sun Rise : ${snapshot.data?.SunRise}")
),
));
}
}))))
read more about null safety