Non nullable instance field must be initalised - json

im new to Dart-flutter.
i have watching a tutorial video from udemy course writing in dart pad
so i also wrote in dartpad. but it showing error in it.
this is the code wrote in udemy..
import 'dart:convert';
void main(){
var rawJson = '{"url": "https://helo.com","id": 2}';
var parsedJson = json.decode(rawJson);
var imageModel = new ImageModel.fromJson(parsedJson);
print(imageModel.url);
}
class ImageModel{
int id;
String url;
ImageModel.fromJson(parsedJson) {
id = parsedJson['id'];
url = parsedJson['url'];
}
ImageModel(this.id, this.url);
}
in that video it runs, but for me it shows error as
Error compiling to JavaScript:
Info: Compiling with sound null safety
Warning: Interpreting this as package URI, 'package:dartpad_sample/main.dart'.
lib/main.dart:15:3:
Error: This constructor should initialize field 'id' because its type 'int' doesn't allow null.
ImageModel.fromJson(parsedJson) {
^
lib/main.dart:12:7:
Info: 'id' is defined here.
int id;
^^
lib/main.dart:15:3:
Error: This constructor should initialize field 'url' because its type 'String' doesn't allow null.
ImageModel.fromJson(parsedJson) {
^
lib/main.dart:13:10:
Info: 'url' is defined here.
String url;
^^^
Error: Compilation failed.
i have no idea what the problem is..
can you guys help me to troubleshoot the error

Since you're compiling with null safety, you may change to this:
int? id;
String? url;
For further info about null safety, please refer to this link https://dart.dev/null-safety

Try using null safe code:
eg:
int? id;
String? url;

You will try like this
import 'dart:convert';
class ImageModel{
final int id;
final String url;
ImageModel({required this.id, required this.url});
factory ImageModel.fromJson(Map<String, dynamic> parsedJson) {
return ImageModel(
id: parsedJson['id'] as int,
url: parsedJson['url'] as String,
);
}
}
void main() {
var rawJson = '{"url": "https://helo.com","id": 2}';
var parsedJson = json.decode(rawJson);
print(parsedJson['url']);
print(parsedJson['id']);
}

You are probably watching tutorial that was recorded before null-safety introduction in Dart (null-safety is a Dart feature that helps prevent NullRefference exceptions in runtime).
You can either go with nullable values (like #Sowat Kheang suggested in another answer) for id and url in ImageModel class (change String to String? and int to int?). Then you will be fine, but it defeats the purpose of null-safety.
Or you can change your code so it will handle null values in proper way. Code will look something like this:
import 'dart:convert';
void main(){
var rawJson = '{"url": "https://helo.com","id": 2}';
var parsedJson = json.decode(rawJson);
var imageModel = ImageModel.fromJson(parsedJson);
print(imageModel.url);
}
class ImageModel{
// Make your fields 'final' if you don't plan to change them later
// this will make your life easier and is a good practice.
final int id;
final String url;
// we add curly braces to make arguments named
// and add 'required' keyword to indicate that constructor can't be called
// without actually passing arguments into it
ImageModel({required this.id, required this.url});
// here we use factory constructor that will call our default constructor
// it's also a good practice to specify type of a variable if you know it (Map<String, dynamic> in this case)
factory ImageModel.fromJson(Map<String, dynamic> parsedJson) {
// since we don't know for sure if 'parsedJson' has key 'id'
// we would add '??' — null checking operator.
// So if parsedJson['id'] is null, value -1 will be passed
// to the constructor. Same with 'parsedJson['url']'.
return ImageModel(
id: parsedJson['id'] ?? -1,
url: parsedJson['url'] ?? '');
}
}

var rawJson = '{"url": "https://helo.com","id": 2}';
Actually it is a Sting Json and Encoding is not perform properly So follow the step..
Map data={"url": "https://helo.com","id": 2};
Encode that data. json.encode(data);
Now the Encoding is done then you can send the data any server if you have..
When you get back data then... json.decode(rawData)
Then parsing work properly

Related

Trying to get city name from json but getting null return

I am new to dart and following a this post to get my data from json:
https://medium.com/flutter-community/converting-json-into-class-objects-in-dart-abcc3cc05478
I am getting weather data from api source which gives me to much info. I only want city name first, then onto try get current temp of that city, i pass into api.
i using https://jsonformatter.org/json-to-dart to format into classes.
I just trying to get city name first from json. but getting null return. It is due to City is a MAP???
name = city
i am getting all the data back with 200 response
jsonclass.dart
code:import 'dart:convert';
import 'package:http/http.dart' as http;
import 'apikey.dart';
import 'jasonclasscity.dart';
class WeatherApiException implements Exception {
const WeatherApiException(this.message);
final String message;
}
void main() async {
String url =
'https://api.openweathermap.org/data/2.5/forecast?q=Palm%20Springs&units=imperial';
final httpUrl = Uri.parse('$url$appid');
final response = await http.get(httpUrl);
if (response.statusCode != 200) {
print(response.statusCode);
throw WeatherApiException('Error getting city: xxxxx');
}
print(response.statusCode);
var body = response.body;
print(response.body);
City city = City.fromJson(jsonDecode(body.toString()));
print(city.toString());
}
jsonclasscity.dart
class City {
// final int id;
final String name; //need this
// final Coord coord;
// final String country;
// final int population;
// final int timezone;
// final int sunrise;
// final int sunset;
City(
{
// required this.id,
required this.name
//required this.coord,
//required this.country,
//required this.population,
//required this.timezone,
//required this.sunrise,
//required this.sunset,
});
factory City.fromJson(Map<String, dynamic> json) {
return City(
name: json ["name"],
); // City
}
}
class Coord {
final double lat;
final double lon;
Coord({
required this.lat,
required this.lon,
});
}
class MainClass {
MainClass({
required this.temp, //need this
required this.feelsLike,
required this.tempMin,
required this.tempMax,
required this.pressure,
required this.seaLevel,
required this.grndLevel,
required this.humidity,
required this.tempKf,
});
final double temp;
final double feelsLike;
final double tempMin;
final double tempMax;
final int pressure;
final int seaLevel;
final int grndLevel;
final int humidity;
final double tempKf;
}
json api data back from call:
{"cod":"200","message":0,"cnt":40,"list":[{"dt":1662498000,"main":{"temp":107.73,"feels_like":106.95,"temp_min":107.73,"temp_max":110.3,"pressure":1009,"sea_level":1009,"grnd_level":995,"humidity":18,"temp_kf":-1.43},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":8.03,"deg":123,"gust":8.99},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-06 21:00:00"},{"dt":1662508800,"main":{"temp":108.37,"feels_like":107.17,"temp_min":108.37,"temp_max":109.33,"pressure":1009,"sea_level":1009,"grnd_level":994,"humidity":17,"temp_kf":-0.53},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":1},"wind":{"speed":7.38,"deg":129,"gust":6.78},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-07 00:00:00"},{"dt":1662519600,"main":{"temp":99.99,"feels_like":99.14,"temp_min":99.99,"temp_max":99.99,"pressure":1011,"sea_level":1011,"grnd_level":995,"humidity":24,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":4},"wind":{"speed":0.94,"deg":283,"gust":4.56},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-07 03:00:00"},{"dt":1662530400,"main":{"temp":95.72,"feels_like":95.07,"temp_min":95.72,"temp_max":95.72,"pressure":1013,"sea_level":1013,"grnd_level":997,"humidity":29,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":2},"wind":{"speed":0.25,"deg":324,"gust":3.56},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-07 06:00:00"},{"dt":1662541200,"main":{"temp":91.53,"feels_like":91.89,"temp_min":91.53,"temp_max":91.53,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":37,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":2.33,"deg":90,"gust":4.29},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-07 09:00:00"},{"dt":1662552000,"main":{"temp":87.82,"feels_like":89.73,"temp_min":87.82,"temp_max":87.82,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":47,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":1.9,"deg":95,"gust":3.31},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-07 12:00:00"},{"dt":1662562800,"main":{"temp":87.26,"feels_like":94.03,"temp_min":87.26,"temp_max":87.26,"pressure":1017,"sea_level":1017,"grnd_level":1000,"humidity":61,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":4.27,"deg":94,"gust":5.46},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-07 15:00:00"},{"dt":1662573600,"main":{"temp":94.55,"feels_like":100.96,"temp_min":94.55,"temp_max":94.55,"pressure":1016,"sea_level":1016,"grnd_level":1000,"humidity":45,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":5.3,"deg":103,"gust":6.13},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-07 18:00:00"},{"dt":1662584400,"main":{"temp":101.66,"feels_like":102.16,"temp_min":101.66,"temp_max":101.66,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":25,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":5.75,"deg":98,"gust":8.25},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-07 21:00:00"},{"dt":1662595200,"main":{"temp":102.78,"feels_like":101.17,"temp_min":102.78,"temp_max":102.78,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":20,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":6.42,"deg":117,"gust":7.74},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-08 00:00:00"},{"dt":1662606000,"main":{"temp":96.26,"feels_like":96.26,"temp_min":96.26,"temp_max":96.26,"pressure":1013,"sea_level":1013,"grnd_level":997,"humidity":30,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":5.26,"deg":117,"gust":6.46},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-08 03:00:00"},{"dt":1662616800,"main":{"temp":93.09,"feels_like":92.77,"temp_min":93.09,"temp_max":93.09,"pressure":1013,"sea_level":1013,"grnd_level":997,"humidity":33,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":2.75,"deg":280,"gust":3.29},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-08 06:00:00"},{"dt":1662627600,"main":{"temp":91.8,"feels_like":90.66,"temp_min":91.8,"temp_max":91.8,"pressure":1011,"sea_level":1011,"grnd_level":995,"humidity":32,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":4.63,"deg":296,"gust":5.26},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-08 09:00:00"},{"dt":1662638400,"main":{"temp":82.94,"feels_like":86.76,"temp_min":82.94,"temp_max":82.94,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":64,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"clouds":{"all":0},"wind":{"speed":2.04,"deg":31,"gust":3.67},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-08 12:00:00"},{"dt":1662649200,"main":{"temp":86.65,"feels_like":91.22,"temp_min":86.65,"temp_max":86.65,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":57,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":4.79,"deg":111,"gust":5.73},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-08 15:00:00"},{"dt":1662660000,"main":{"temp":91.9,"feels_like":97.29,"temp_min":91.9,"temp_max":91.9,"pressure":1010,"sea_level":1010,"grnd_level":994,"humidity":48,"temp_kf":0},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03d"}],"clouds":{"all":38},"wind":{"speed":5.3,"deg":97,"gust":4.43},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-08 18:00:00"},{"dt":1662670800,"main":{"temp":99.64,"feels_like":102.29,"temp_min":99.64,"temp_max":99.64,"pressure":1007,"sea_level":1007,"grnd_level":991,"humidity":31,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"clouds":{"all":82},"wind":{"speed":6.49,"deg":103,"gust":7.18},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-08 21:00:00"},{"dt":1662681600,"main":{"temp":98.38,"feels_like":100.67,"temp_min":98.38,"temp_max":98.38,"pressure":1004,"sea_level":1004,"grnd_level":989,"humidity":32,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":91},"wind":{"speed":4.27,"deg":115,"gust":5.57},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-09 00:00:00"},{"dt":1662692400,"main":{"temp":94.01,"feels_like":96.22,"temp_min":94.01,"temp_max":94.01,"pressure":1005,"sea_level":1005,"grnd_level":989,"humidity":38,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":98},"wind":{"speed":0.43,"deg":302,"gust":2.59},"visibility":10000,"pop":0.08,"sys":{"pod":"n"},"dt_txt":"2022-09-09 03:00:00"},{"dt":1662703200,"main":{"temp":91.24,"feels_like":92.17,"temp_min":91.24,"temp_max":91.24,"pressure":1004,"sea_level":1004,"grnd_level":988,"humidity":39,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":98},"wind":{"speed":3.06,"deg":286,"gust":3.47},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-09 06:00:00"},{"dt":1662714000,"main":{"temp":81.39,"feels_like":83.91,"temp_min":81.39,"temp_max":81.39,"pressure":1006,"sea_level":1006,"grnd_level":990,"humidity":62,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":100},"wind":{"speed":4.63,"deg":62,"gust":6.29},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-09 09:00:00"},{"dt":1662724800,"main":{"temp":79,"feels_like":79,"temp_min":79,"temp_max":79,"pressure":1005,"sea_level":1005,"grnd_level":989,"humidity":71,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":100},"wind":{"speed":2.51,"deg":60,"gust":4.79},"visibility":10000,"pop":0,"sys":{"pod":"n"},"dt_txt":"2022-09-09 12:00:00"},{"dt":1662735600,"main":{"temp":80.55,"feels_like":83.55,"temp_min":80.55,"temp_max":80.55,"pressure":1006,"sea_level":1006,"grnd_level":990,"humidity":68,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":100},"wind":{"speed":3.8,"deg":64,"gust":5.48},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-09 15:00:00"},{"dt":1662746400,"main":{"temp":87.75,"feels_like":90.99,"temp_min":87.75,"temp_max":87.75,"pressure":1006,"sea_level":1006,"grnd_level":990,"humidity":51,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":100},"wind":{"speed":8.95,"deg":91,"gust":17.07},"visibility":10000,"pop":0,"sys":{"pod":"d"},"dt_txt":"2022-09-09 18:00:00"},{"dt":1662757200,"main":{"temp":83.46,"feels_like":87.93,"temp_min":83.46,"temp_max":83.46,"pressure":1005,"sea_level":1005,"grnd_level":989,"humidity":65,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":100},"wind":{"speed":9.75,"deg":102,"gust":15.77},"visibility":10000,"pop":0.16,"sys":{"pod":"d"},"dt_txt":"2022-09-09 21:00:00"},{"dt":1662768000,"main":{"temp":80.98,"feels_like":84.6,"temp_min":80.98,"temp_max":80.98,"pressure":1004,"sea_level":1004,"grnd_level":988,"humidity":70,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":9.42,"deg":79,"gust":24.18},"visibility":10000,"pop":0.37,"rain":{"3h":1.03},"sys":{"pod":"d"},"dt_txt":"2022-09-10 00:00:00"},{"dt":1662778800,"main":{"temp":76.71,"feels_like":78.13,"temp_min":76.71,"temp_max":76.71,"pressure":1004,"sea_level":1004,"grnd_level":988,"humidity":86,"temp_kf":0},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":10.13,"deg":16,"gust":15.84},"visibility":3866,"pop":0.88,"rain":{"3h":8.03},"sys":{"pod":"n"},"dt_txt":"2022-09-10 03:00:00"},{"dt":1662789600,"main":{"temp":77.85,"feels_like":79.41,"temp_min":77.85,"temp_max":77.85,"pressure":1005,"sea_level":1005,"grnd_level":989,"humidity":87,"temp_kf":0},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":8.9,"deg":67,"gust":15.05},"visibility":2520,"pop":1,"rain":{"3h":13.28},"sys":{"pod":"n"},"dt_txt":"2022-09-10 06:00:00"},{"dt":1662800400,"main":{"temp":76.24,"feels_like":78.08,"temp_min":76.24,"temp_max":76.24,"pressure":1005,"sea_level":1005,"grnd_level":988,"humidity":96,"temp_kf":0},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":8.21,"deg":85,"gust":12.82},"visibility":284,"pop":0.99,"rain":{"3h":14.58},"sys":{"pod":"n"},"dt_txt":"2022-09-10 09:00:00"},{"dt":1662811200,"main":{"temp":73.42,"feels_like":74.88,"temp_min":73.42,"temp_max":73.42,"pressure":1007,"sea_level":1007,"grnd_level":991,"humidity":94,"temp_kf":0},"weather":[{"id":502,"main":"Rain","description":"heavy intensity rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":6.73,"deg":89,"gust":12.12},"visibility":519,"pop":1,"rain":{"3h":18.39},"sys":{"pod":"n"},"dt_txt":"2022-09-10 12:00:00"},{"dt":1662822000,"main":{"temp":74.17,"feels_like":75.52,"temp_min":74.17,"temp_max":74.17,"pressure":1010,"sea_level":1010,"grnd_level":993,"humidity":90,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":100},"wind":{"speed":4.45,"deg":82,"gust":7.65},"visibility":853,"pop":1,"rain":{"3h":2.28},"sys":{"pod":"d"},"dt_txt":"2022-09-10 15:00:00"},{"dt":1662832800,"main":{"temp":76.66,"feels_like":77.92,"temp_min":76.66,"temp_max":76.66,"pressure":1011,"sea_level":1011,"grnd_level":994,"humidity":83,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":99},"wind":{"speed":5.95,"deg":98,"gust":10.58},"visibility":4886,"pop":1,"rain":{"3h":1.15},"sys":{"pod":"d"},"dt_txt":"2022-09-10 18:00:00"},{"dt":1662843600,"main":{"temp":79.83,"feels_like":79.83,"temp_min":79.83,"temp_max":79.83,"pressure":1010,"sea_level":1010,"grnd_level":994,"humidity":73,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":99},"wind":{"speed":4.59,"deg":98,"gust":9.37},"visibility":10000,"pop":0.75,"rain":{"3h":1.11},"sys":{"pod":"d"},"dt_txt":"2022-09-10 21:00:00"},{"dt":1662854400,"main":{"temp":80.85,"feels_like":84.36,"temp_min":80.85,"temp_max":80.85,"pressure":1009,"sea_level":1009,"grnd_level":993,"humidity":70,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":99},"wind":{"speed":5.14,"deg":108,"gust":7.31},"visibility":10000,"pop":0.84,"rain":{"3h":1.43},"sys":{"pod":"d"},"dt_txt":"2022-09-11 00:00:00"},{"dt":1662865200,"main":{"temp":79.84,"feels_like":79.84,"temp_min":79.84,"temp_max":79.84,"pressure":1011,"sea_level":1011,"grnd_level":994,"humidity":72,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":3.36,"deg":117,"gust":5.55},"visibility":10000,"pop":0.83,"rain":{"3h":0.84},"sys":{"pod":"n"},"dt_txt":"2022-09-11 03:00:00"},{"dt":1662876000,"main":{"temp":79.72,"feels_like":79.72,"temp_min":79.72,"temp_max":79.72,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":73,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"clouds":{"all":98},"wind":{"speed":1.03,"deg":40,"gust":3.29},"visibility":10000,"pop":0.75,"rain":{"3h":0.16},"sys":{"pod":"n"},"dt_txt":"2022-09-11 06:00:00"},{"dt":1662886800,"main":{"temp":79.48,"feels_like":79.48,"temp_min":79.48,"temp_max":79.48,"pressure":1012,"sea_level":1012,"grnd_level":995,"humidity":72,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":95},"wind":{"speed":2.1,"deg":84,"gust":4.72},"visibility":10000,"pop":0.05,"sys":{"pod":"n"},"dt_txt":"2022-09-11 09:00:00"},{"dt":1662897600,"main":{"temp":79.5,"feels_like":79.5,"temp_min":79.5,"temp_max":79.5,"pressure":1012,"sea_level":1012,"grnd_level":996,"humidity":73,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04n"}],"clouds":{"all":96},"wind":{"speed":3.47,"deg":104,"gust":4.63},"visibility":10000,"pop":0.08,"sys":{"pod":"n"},"dt_txt":"2022-09-11 12:00:00"},{"dt":1662908400,"main":{"temp":79.7,"feels_like":79.7,"temp_min":79.7,"temp_max":79.7,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":73,"temp_kf":0},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"clouds":{"all":99},"wind":{"speed":3.13,"deg":96,"gust":4.18},"visibility":10000,"pop":0.05,"sys":{"pod":"d"},"dt_txt":"2022-09-11 15:00:00"},{"dt":1662919200,"main":{"temp":84.87,"feels_like":88.41,"temp_min":84.87,"temp_max":84.87,"pressure":1014,"sea_level":1014,"grnd_level":998,"humidity":58,"temp_kf":0},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"clouds":{"all":84},"wind":{"speed":4.52,"deg":94,"gust":5.99},"visibility":10000,"pop":0.03,"sys":{"pod":"d"},"dt_txt":"2022-09-11 18:00:00"}],"city":{"id":5380668,"name":"Palm Springs","coord":{"lat":33.8303,"lon":-116.5453},"country":"US","population":44552,"timezone":-25200,"sunrise":1662470615,"sunset":1662516349}}
I've not dug into your code, but I can pretty much guarantee that your issue will be down to you not querying the correct nested level of the JSON Object. Looking at the JSON data you get back from the API call, within the main Object, there is then a 'City' Object, which has the key 'name' against it. Make sure you're querying the correct level.
The structure you need to get the data you need is essentially the following pseudo code: JsonObjectFromAPIResponse.get("city").get("name")
Just translate this into what you're doing. Debug it step by step. You're over complicating it in your code example before you've got the basics working. Forget about the City Objects and Factories you've been creating, just get it working in a single file, then refactor it after.
thanks for response. i was able to figure out the correct way to walk down the json tree. i was just coding the format incorrect.
this worked
print('justcity name:');
// printout Palm SPrings ok.
print(data['city']['name']);
//print(justList[0]);
final justTemp = data['list'][0]['main']['temp'];
print('justTemp:');
this json tool help me understand the json tree better for my very long and complex json response from host api.
https://jsonpathfinder.com/

jsonEncode throwing exceptions encoding a simple class

Friends
I have a simple Dart class that cannot be encoded into JSON.
The output of the following code prints out to the console
flutter: Converting object to an encodable object failed: Instance of 'TestJsonConversion'
class TestJsonConversion {
String testString = "123245abcde";
int testIneger = 1234;
}
void main() {
var testJsonConversion = TestJsonConversion();
try {
var testString = jsonEncode(testJsonConversion);
// ignore: avoid_print
print(testString);
}catch(e){
// ignore: avoid_print
print(e.toString());
}
runApp(const MyApp());
}
This is the default application generated by Visual Studio with just these lines added.
You cannot encode an instance of a user class with the built-in jsonEncode. These are things you can encode by default: "a number, boolean, string, null, list or a map with string keys". For this class to encode, you'd have to define a .toJson method on it, and I don't see one there.
The class has no constructors and tojson . Try this
class TestJsonConversion {
final String testString;
final int testInteger;
TestJsonConversion(this.testString, this.testInteger);
TestJsonConversion.fromJson(Map<String, dynamic> json)
: testString = json['trstString'],
testInteger = json['testInteger'];
Map<String, dynamic> toJson() => {
'testString': testString,
'testInteger': testInteger,
};
}
And when you create an instance
var testJsonConversion = TestJsonConversion(testString: 'abc', testInteger: 123);
print(json.encode(testJsonConversion.toJson());

Dart - Can I handle null value from json.decode when the key we put is wrong

Can we handle null value output from json.decode? I already try using if else function, but it doesn't really works well.
import 'dart:convert';
var typeCat = "WrongKey";
var endPoint = "WrongKey";
void main() async {
final base = RetryClient(http.Client());
String outputJSON = await base.read(
Uri.parse("http://estra-api.herokuapp.com/api/${typeCat}/${endPoint}"));
final link_decode = json.decode(outputJSON)["link"] as String;
final text_decode = json.decode(outputJSON)["text"] as String;
print(link_decode);
print(text_decode);
}
Is there anything I can do with these codes?
I can't be 100% sure since you didn't share the full error message, but the problem seem to be that you're trying to cast to a non-nullable String a value that can possibly be null.
final link_decode = json.decode(outputJSON)["link"] as String?;
final text_decode = json.decode(outputJSON)["text"] as String?;
and if you want to assign a default value for them you can also:
final link_decode = json.decode(outputJSON)["link"] ?? 'default';
final text_decode = json.decode(outputJSON)["text"] ?? 'default';
This will allow link_decode and text_decode to have null as value
Try this and if you don't succede share the error message.

Flutter migrating to null safety, late or nullable?

I would like to migrate to null safety correctly but I am not sure exactly when to use late and when to use nullable. I have read Flutter's Understanding null safety article and finished the Null Safety codelabs but I don't know if I have understood it correctly. New to Flutter and Dart, trying to catch this null safety migration curve ball here in five different scenarios:
Parsing from JSON to dart
Initialising variables
Passing data from MaterialPageRoute
http database helper class
sqflite database helper class
Case 1: Parsing from JSON to dart
I am fetching data with http from a MySQL database and using quicktype.io to parse JSON to dart. The non null-safety code of my data model looks like this:
// To parse this JSON data, do
//
// final someList = someListFromJson(jsonString);
import 'dart:convert';
List<SomeList> someListFromJson(String str) =>
List<SomeList>.from(json.decode(str).map((x) => SomeList.fromJson(x)));
String someListToJson(List<SomeList> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class SomeList {
SomeList({
this.someId,
this.somebody,
});
String someId;
String somebody;
factory SomeList.fromJson(Map<String, dynamic> json) => SomeList(
someId: json["someId"],
somebody: json["somebody"],
Map<String, dynamic> toJson() => {
"someId": someId,
"somebody": somebody,
};
}
Using dart migrate, they suggested that I Changed type 'String' to be nullable.
However, I know for a fact though that in my json data, someId is never and cannot be null, while somebody could be null. Should I still use the ? nullable type for the sake of initialising? My understanding is that I should not use the ! null assertion operator for somebody since it technically does not have a value yet. Well, then does that mean I should use the late keyword instead?
String? someId;
String? somebody;
or
late String someId;
late String somebody;
Case 2: Initialising variables
I call SomeList in a Stateful widget on one of my screens as a Future.
Old code:
class _SomeScreenState extends State<SomeScreen > {
Future<List<VocabList>> futureList;
Once again it is proposing that I make it nullable, like so:
Future<List<VocabList > >? futureList;
Am I right to understand that I use the ? nullable type for initialising Future<List<VocabList>>?
Case 3: Passing data from MaterialPageRoute
I am passing data from MaterialPageRoute as such:
MaterialPageRoute(
builder: (context) => SomeScreen(
someId: something[index].someId,
somebody: something[index].somebody,
On the receiving end, the old code looks like this:
class SomeScreen extends StatefulWidget {
final String someId;
final String somebody;
SomeScreen({
Key? key,
#required this.someId,
#required this.somebody,
Again it is recommending I set my two final variables someId and somebody as nullable but should they be nullable or are they just late?
Should I do this?
class SomeScreen extends StatefulWidget {
final String? someId;
final String? somebody;
SomeScreen({
Key? key,
#required this.someId,
#required this.somebody,
or
class SomeScreen extends StatefulWidget {
late final String someId;
late final String somebody;
SomeScreen({
Key? key,
#required this.someId,
#required this.somebody,
Case 4: http database helper class
I am passing the variable someName with a button to a http request.
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:test/models/something_list.dart';
List<SomethingList > _list = [];
String someName;
class Somebody {
static const String url = 'http://localhost/~idunno/api_search.php';
static Future<List<SomeList > > getData(String someName) async {
try {
http.Response response =
await http.get(Uri.parse(url + '?q=' + someName));
someName cannot be null or else the http request will fail. Should I still declare it as nullable and handle the failure using on FormatException like so?
List<SomethingList > _list = [];
String? someName;
// some code omitted
on FormatException {
throw InvalidFormatException('Something is not right here');
Case 5: sqflite database helper class
Old code:
static Database _database;
Future<Database> get database async {
if (_database != null) return _database;
// lazily instantiate the db the first time it is accessed
_database = await _initDatabase();
return _database;
}
// some code omitted
Future<bool > checkBookmark(String someId) async {
Database db = await instance.database;
var bookmarked = await db.query(table,
where: 'someId = ?',
whereArgs: [someId]);
return bookmarked.isEmpty ? false : true;
}
Two questions here: (1) Like the above-mentioned scenarios, do I make Database and Future<Database> nullable because of initialisation? (2) What does Added a cast to an expression (non-downcast) mean?
Suggested null safety changes:
static Database? _database;
Future<Database?> get database async {
if (_database != null) return _database;
// lazily instantiate the db the first time it is accessed
_database = await _initDatabase();
return _database;
}
// some code omitted
Future<bool > checkBookmark(String? someId) async {
Database db = await (instance.database as FutureOr<Database>);
var bookmarked = await db.query(table,
where: 'someId = ?',
whereArgs: [someId]);
return bookmarked.isEmpty ? false : true;
}
Any help on this will be much appreciated and I hope the answers will help other new coders with migrating to null safety as well!
To answer my own question, or questions... Disclaimer: I have no Dart errors after making the changes below but my code isn't exactly working so the solution might not be 100% correct.
Case 1: Parsing from JSON to dart
Since quicktype is null-safe yet, I have opted for json_serializable do my JSON to dart conversion.
Case 2: Initialising variables
Instead of declaring <FutureList<List>> as nullable, I have added a type to my FutureBuilder.
child: FutureBuilder<List<VocabList>>(
Case 3: Passing data from MaterialPageRoute
I no longer have to declare the variables as nullable.
Case 4: http database helper class
Did not use the nullable constructor but instead used late.
late String someName;
Case 5: sqflite database helper class
New code here:
// Initialise the database.
// Only allow a single open connection to the database.
static Database? _database; // Added ? for null-safety
Future<Database> get database async {
if (_database != null)
return _database as Future<Database>; // Added 'as type' for null-safety
_database = await _initDatabase();
return _database as Future<Database>; // Added 'as type' for null-safety
}
If anybody spots any errors or knows how I can do this better, please let me know!

Parsing issue with Dart - [no build value ^ serializable ^ ]

Aye Aye good people,
[edited:
running this in dartpad
import 'dart:convert';
void main() {
const String _json = '{"myListInt": [1]}';
final Map<String, dynamic> _map = jsonDecode(_json);
final List<int> _list = _map['myListInt'] as List<int>;
_list.forEach((i) {
String _s = i.toString();
print(_s);
});
}
returns
Uncaught exception:
CastError: Instance of 'JSArray': type 'JSArray' is not a subtype of type
'List<int>'
in case I use
final List<int> _list = List<int>.from(_map['myListInt'] as List<int>);
or
List<int>.generate(_map['myListInt'].length, (i)=>_map['myListInt'][i] as int);
returns
Uncaught exception:
Cannot read property 'length' of undefined
]
what am I doing wrong?
Thank you in advance
Francesco
Instead of this line
myListInt: List<int>.from(_map['myListInt'] as List<int>),
you can use
myListInt: List<int>.generate(_map['myListInt'].length, (i)=>_map['myListInt'][i] as int
Basically instead of casting the whole list, you have to cast each element one by one.
ok, using ""as Iterable"" works,
import 'dart:convert';
void main() {
const String _json = '{"myListInt": [1]}';
final Map<String, dynamic> _map = jsonDecode(_json);
final List<int> _list= List<int>.from(_map['myListInt'] as Iterable);
_list.forEach((i) {
String _s = i.toString();
print(_s);
});
}