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'
Related
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>
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].
I request data with axios.get(...), successful get the return as nested objects. I can access the data.message, data.cnt, data.cod but I can't access the properties of the "city". kept getting undefine or typeerror.
I want to access the properties of the city object nested within the response data. like this "data.city.name" but errors.
{
"cod": "200",
"message": 0.0051,
"cnt": 40,
"list": [
{
"dt": 1545318000,
"main": {
"temp": 282.74,
"temp_min": 282.167,
"temp_max": 282.74,
"pressure": 1012.86,
"sea_level": 1020.54,
"grnd_level": 1012.86,
"humidity": 84,
"temp_kf": 0.57
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"clouds": { "all": 44 },
"wind": { "speed": 5.67, "deg": 243.503 },
"rain": { "3h": 0.25 },
"sys": { "pod": "d" },
"dt_txt": "2018-12-20 15:00:00"
},
{
"dt": 1545739200,
"main": {
"temp": 282.628,
"temp_min": 282.628,
"temp_max": 282.628,
"pressure": 1037.58,
"sea_level": 1045.29,
"grnd_level": 1037.58,
"humidity": 100,
"temp_kf": 0
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"clouds": { "all": 76 },
"wind": { "speed": 2.02, "deg": 212.503 },
"rain": { "3h": 0.13 },
"sys": { "pod": "d" },
"dt_txt": "2018-12-25 12:00:00"
}
],
"city": {
"id": 2643743,
"name": "London",
"coord": { "lat": 51.5073, "lon": -0.1277 },
"country": "GB",
"population": 1000000
}
}
Use JSON.parse();
Example:
var data = JSON.parse(yourJSONObject)
console.log(data.city.name)
May not full represent what you need, but this should show how to set a default state, fetch your results, and then pass them into components. Your object is fine, I feel like you might be trying to access it before Axios completes.
export class DataView extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
data: {}
};
this.defaultState = {
// default properties of state
};
}
componentWillMount() {
this.fetchData();
}
fetchData = () => {
await axios.get( ${apiEndpoint}${inputCity}&appid=${apiKey} )
.then( data => {
this.setState({
data,
...this.defaultState,
isLoading: false
});
});
};
render() {
return (
<Fragment>
{this.state.isLoading ? ( // Check if it's still loading and load nothing if true
<Fragment />
) : (
<Component withProps={this.state.data}></Component> // Data can be accessed if isLoading: false
)}
</Fragment>
);
}
}
if you are getting data.message, then you must get the city name with data.city.name
I think you have some errors in your code because i can access the data and the json is also valid too.
try to console.log() the response and see what's going on.
Seems to work fine with data.city.name
const data = {
"cod": "200",
"message": 0.0051,
"cnt": 40,
"list": [
{
"dt": 1545318000,
"main": {
"temp": 282.74,
"temp_min": 282.167,
"temp_max": 282.74,
"pressure": 1012.86,
"sea_level": 1020.54,
"grnd_level": 1012.86,
"humidity": 84,
"temp_kf": 0.57
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"clouds": { "all": 44 },
"wind": { "speed": 5.67, "deg": 243.503 },
"rain": { "3h": 0.25 },
"sys": { "pod": "d" },
"dt_txt": "2018-12-20 15:00:00"
},
{
"dt": 1545739200,
"main": {
"temp": 282.628,
"temp_min": 282.628,
"temp_max": 282.628,
"pressure": 1037.58,
"sea_level": 1045.29,
"grnd_level": 1037.58,
"humidity": 100,
"temp_kf": 0
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"clouds": { "all": 76 },
"wind": { "speed": 2.02, "deg": 212.503 },
"rain": { "3h": 0.13 },
"sys": { "pod": "d" },
"dt_txt": "2018-12-25 12:00:00"
}
],
"city": {
"id": 2643743,
"name": "London",
"coord": { "lat": 51.5073, "lon": -0.1277 },
"country": "GB",
"population": 1000000
}
}
document.write(data.city.name);
getData = async () => {
const { inputCity } = this.state;
try {
const data = await axios.get(${apiEndpoint}${inputCity}&appid=${apiKey});
this.setState({ data });
console.log(this.state.data);
return data;
} catch (err) {
console.error(err);
}
}
I'm trying to access to a JSON array returned by a OpenWeatherMap request.
The JSON data is:
{ "city":
{ "id": 3171457, "name": "New York", "coord": { "lon": 0.32898, "lat": 4.802662 }, "country": "US", "population": 0, "sys": { "population": 0 } },
"cod": "200", "message": 0.0317, "cnt": 40,
"list": [ { "dt": 1483552800, "main": { "temp": 277.28, "temp_min": 275.705, "temp_max": 277.28, "pressure": 1013.85, "sea_level": 1021.42, "grnd_level": 1013.85, "humidity": 93, "temp_kf": 1.57 }, "weather": [ { "id": 800, "main": "Clear", "description": "clear sky", "icon": "01n" } ], "clouds": { "all": 0 }, "wind": { "speed": 4.74, "deg": 269.002 }, "sys": { "pod": "n" }, "dt_txt": "2017-01-04 18:00:00" },
...
If i use in a template {{payload.list}} I see a list of [object Object]s.
But if I use {{payload.list[0]}}, or {{payload.list[0].main}}, I see nothing - my guess was a single [object Object].
How can i access to the first member and inner members?
The template node uses the mustache format, documented here: https://mustache.github.io/mustache.5.html
To access array values, you should use the following syntax:
{{ payload.list.0 }}
and
{{ payload.list.0.main }}
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.