Json.decode doesn't work with json from assets - json

This line doesn't work, and the code gets stocked there.
var list = json.decode(response) as List<dynamic>;
The response String that I submit is:
final String response = await rootBundle.loadString('assets/madrid.json');
With this JSON:
{
"coord": {
"lon": -3.7026,
"lat": 40.4165
},
"weather": [{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01n"
}],
"base": "stations",
"main": {
"temp": 297.84,
"feels_like": 297.62,
"temp_min": 294.82,
"temp_max": 299.94,
"pressure": 1017,
"humidity": 48
},
"visibility": 10000,
"wind": {
"speed": 1.34,
"deg": 270,
"gust": 2.68
},
"clouds": {
"all": 0
},
"dt": 1631051279,
"sys": {
"type": 2,
"id": 2007545,
"country": "ES",
"sunrise": 1630993686,
"sunset": 1631039875
},
"timezone": 7200,
"id": 3117735,
"name": "Madrid",
"cod": 200
}
The line doesn't execute and gets stuck there. I tried with other JSON responses, and it worked, but I don't know why this one doesn't.

remove as List<dynamic> from
The problem is you are trying to decode Map data as List
If you face Unable to load asset error add your json path into pubspec.yaml
You need to make sure json is response the same type if want to typecast.
Following json will work fine with as List<dynamic>
[
{ "key1": "value" },
{ "key2": "value" },
{ "key3": "value" },
{ "key4": "value" }
]
Example with above json file
final String response = await rootBundle.loadString('assets/list.json');
var dataTypeCast = json.decode(response) as List<dynamic>;
print(dataTypeCast.runtimeType); //List<dynamic>
better approach is removing type casting when decoding unknown response
final String response = await rootBundle.loadString('assets/list.json');
var data = json.decode(response);
print(data.runtimeType); // List<dynamic>

Related

Problem getting data from json through http with riverpod

I have this json:
{
"coord": {
"lon": -3.7026,
"lat": 40.4165
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01n"
}
],
"base": "stations",
"main": {
"temp": 297.84,
"feels_like": 297.62,
"temp_min": 294.82,
"temp_max": 299.94,
"pressure": 1017,
"humidity": 48
},
"visibility": 10000,
"wind": {
"speed": 1.34,
"deg": 270,
"gust": 2.68
},
"clouds": {
"all": 0
},
"dt": 1631051279,
"sys": {
"type": 2,
"id": 2007545,
"country": "ES",
"sunrise": 1630993686,
"sunset": 1631039875
},
"timezone": 7200,
"id": 3117735,
"name": "Madrid",
"cod": 200
}
with this link:
http://api.openweathermap.org/data/2.5/weather?id=3117735&appid=899fc742471c1a7623a573d0bc7ad85b
I want to get the data, to make that I created the class with a json convert, and get want to get the data through a json.decode:
Future<Madrid> fetchMadrid() async {
final response = await http
.get(Uri.parse('http://api.openweathermap.org/data/2.5/weather?id=3117735&appid=899fc742471c1a7623a573d0bc7ad85b'))
.timeout(const Duration(seconds: 2));
if (response.statusCode == 200) {
return parseMadrid(response.body);
} else {
throw Exception('Error');
}
}
Madrid parseMadrid(String response) {
var list = json.decode(response);
Madrid photos = Madrid.fromJson(list);
return photos;
}
final madridStateProvider = FutureProvider<Madrid>((ref) async {
return fetchMadridLocal();
});
and get the data through a Future Provider with riverbed.
I get the error: Expected a value of type 'Coord', but got one of type '_JsonMap'

ERROR: type 'String' is not a subtype of type 'int' of 'index' while using fromjson in flutter

I am learning TDD(Test Drive Development) in a flutter. Here I am trying to parse my JSON data but every time I run the test I get an error saying this.
ERROR: type 'String' is not a subtype of type 'int' of 'index'
These are my code
weather_app_model_test.dart
group('fromJson', () {
test('should return a valid model', () async {
final Map<String, dynamic> jsonMap =
json.decode(fixture('weather_app.json'));
final result = WeatherAppModel.fromJson(jsonMap);
expect(result, tWeatherAppModel);
});
});
weather_app_model.dart
factory WeatherAppModel.fromJson(Map<String, dynamic> json) {
return WeatherAppModel(
weatherMain: json['weather']['main'],
weatherDescription: json['weather']['description'],
temp: json['main']['temp'],
minTemp: json['main']['temp_min'],
maxTemp: json['main']['temp_main'],
country: json['sys']['country'],
);
}
fixtures/weather_app.json
{
"coord": {
"lon": 78,
"lat": 20
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"base": "model",
"main": {
"temp": 301.51,
"pressure": 1014,
"humidity": 67,
"temp_min": 301.51,
"temp_max": 301.51,
"sea_level": 1014,
"grnd_level": 979
},
"wind": {
"speed": 3.19,
"deg": 77
},
"rain": {
"3h": 1.81
},
"clouds": {
"all": 45
},
"dt": 1572672029,
"sys": {
"country": "IN",
"sunrise": 1572655775,
"sunset": 1572696807
},
"timezone": 19800,
"id": 1272596,
"name": "Digras",
"cod": 200
}
Any help would be great.
factory WeatherAppModel.fromJson(Map<String, dynamic> json) {
return WeatherAppModel(
weatherMain: json['weather'][0]['main'],
weatherDescription: json['weather'][0]['description'],
temp: json['main']['temp'],
minTemp: json['main']['temp_min'],
maxTemp: json['main']['temp_main'],
country: json['sys']['country'],
);
}
This will fix your problem. json['weather'] is not returning like map, its an array. It takes first value with [0].

Weather graph using Angular 2, chart.js and json data

Using weather information that i receive from a service, i am trying to create a graph by means of chart.js.
I imported Chart into my project, and i am capable of using it using static data, but i am unable to use the data that i get from json.
What i am trying currently looks like this:
getForeCast()
{
this.weatherService.getForecastByCityName(this.searchString)
.subscribe(response =>
{
this.lineChartData = response.list.main.temp;
this.lineChartLabels = response.list.dt;
})
}
//LineChart
public lineChartData: Array<any>
public lineChartLabels: Array<any>
the getforecast() is activate in ngOnInit
the info that i receive from the json looks like this:
{
"cod": "200",
"message": 0.0054,
"cnt": 35,
"list": [
{
"dt": 1498748400,
"main": {
"temp": 21.87,
"temp_min": 21.25,
"temp_max": 21.87,
"pressure": 1006.93,
"sea_level": 1009.32,
"grnd_level": 1006.93,
"humidity": 62,
"temp_kf": 0.62
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04d"
}
],
"clouds": {
"all": 56
},
"wind": {
"speed": 6.81,
"deg": 227.001
},
"rain": {},
"sys": {
"pod": "d"
},
"dt_txt": "2017-06-29 15:00:00"
},
if i use the info to show it in a table, it works, but i can not get it to work in the graph.
Look at the update() method of the chart. Maybe you need to trigger it after you update your data in order for the chart to re-render.

How to extract JSON parameter using JsonSlurper in Groovy

I've written the following groovy script in SOAPUI to execute an assertion on a JSON response.
I'm having difficulty writing the assertion to extract and assert on Weather > main > Clouds property and value of the JSON response.
Can someone please assist with correcting my code to extract the value I want?
Thanks!
import groovy.json.JsonSlurper
def json = '''{
"coord": {
"lon": -0.13,
"lat": 51.51
},
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02n"
}
],
"base": "stations",
"main": {
"temp": 281.644,
"pressure": 1027.43,
"humidity": 100,
"temp_min": 281.644,
"temp_max": 281.644,
"sea_level": 1035.14,
"grnd_level": 1027.43
},
"wind": {
"speed": 3.33,
"deg": 43.5005
},
"clouds": {
"all": 12
},
"dt": 1476231232,
"sys": {
"message": 0.0084,
"country": "GB",
"sunrise": 1476253200,
"sunset": 1476292372
},
"id": 2643743,
"name": "London",
"cod": 200
}'''
def result = new JsonSlurper().parseText(json)
log.info(result)
assert result.weather.main == "Clouds"
Weather is an array of maps, as I see. So, you need to select an item or groovy will return to you an array of main.
assert result.weather.first().main == "Clouds"
​assert result.weather.main == ["Clouds"​]​
weather in your json is array. You can access it elements as a regular array
assert result.weather.main[0] == "Clouds"
assert result?.weather?.main?.getAt(0) == "Clouds"
second prefered because it null safe
Looks it's a trivial issue.
weather is an array(in []) and that is why the assertion fails.
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02n"
}
],
If you do result.weather​.main​, then it returns a list which contains an element Clouds. But,not a single value as you expected.
So, you can do:
assert result.weather​[0].main == 'Clouds', 'Not matching the expected result' or
assert result.weather​.main == ['Clouds'] or
assert result.weather.main.contains('Clouds')
For suppose if weather is below (example with more elements in json array):
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02n"
},
{
"id": 802,
"main": "CloudApps",
"description": "few clouds",
"icon": "03n"
}
],
Then assertion can be done
assert result.weather.main == ['Clouds', 'CloudApps']

Access JSON data in UI5

I'm trying to access the JSON data from the below URL:
http://api.openweathermap.org/data/2.5/weather?q=London
And get the below as response:
{
"coord": {
"lon": 174.77,
"lat": -36.87
},
"sys": {
"type": 1,
"id": 8276,
"message": 0.0568,
"country": "GB",
"sunrise": 1407093366,
"sunset": 1407130678
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"base": "cmc stations",
"main": {
"temp": 287.15,
"pressure": 1017,
"humidity": 76,
"temp_min": 287.15,
"temp_max": 287.15
},
"wind": {
"speed": 3.6,
"deg": 210
},
"clouds": {
"all": 76
},
"rain": {
"3h": 1
},
"dt": 1407115800,
"id": 2193733,
"name": "London",
"cod": 200
}
Kindly can you please suggest how do I access it in UI5?
I've done the following in order to set the model:
var jsonModel = new sap.ui.model.json.JSONModel();
jsonModel.loadData('http://api.openweathermap.org/data/2.5/weather?q=Auckland');
sap.ui.getCore().setModel(jsonModel);
I can see the response coming well in Chrome. How do I bind it to ui5 control? I've seen the binding syntax but gets either null or undefined error.
Please suggest.
Awaiting response.
Cheers,
AW
Just sap.ui.getCore().getModel(<your Modelname>).getData()
It's better to avoid the global model. You could use the view instead. Like: this.getView().setModel(new JSONModel(), "yourModel"). The model is bind to the view, so the controls within the view can access the model data.