Closed dario-digregorio closed 4 years ago
I tested the app on different devices and emulators and all have the same result. When I call the link it returns the json.
You need to put parseWeatherLocation method outside your weather Location Class as when using compute the method you pass for parsing must be static if use within in a class or must be outside the class to access the data. Weather Location class must be like this:
WeatherLocation parseWeatherLocation(String json){
return WeatherLocation.fromJson(jsonDecode(json));
}
class HttpService {
final String weatherURL =
'https://api.openweathermap.org/data/2.5/weather?lat=12.8578252&units=metric&lon=66.0999831&appid=
Future
@dario-digregorio
compute is sugar for isolate which need to take a top level
or static
function
I'm not sure that this is the case for parseWeatherLocation
does the code below run?
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter_app/weather_model.dart';
import 'package:http/http.dart';
class HttpService {
final String weatherURL =
'https://api.openweathermap.org/data/2.5/weather?lat=12.8578252&units=metric&lon=66.0999831&appid=<API_KEY>';
Future<WeatherLocation> getWeatherLocation(Client client) async {
Response res = await client.get(weatherURL);
+ return WeatherLocation.fromJson(jsonDecode(res.body);
- return compute(parseWeatherLocation, res.body);
}
- WeatherLocation parseWeatherLocation(String json){
- return WeatherLocation.fromJson(jsonDecode(json));
- }
}
also it's always useful to provide an actually runnable code
(I'm referring to the unusable weatherURL
) otherwise the issue will be hardly workable
@Mashood97 you bested me on the line 🥇
@iapicca hahaha no problem brother when I was playing around with isolates and compute firstly that was the biggest mistake as a beginner I made. @dario-digregorio let me know if the compute now returns your API data.
@iapicca sadly not. I event put the methods in the main and left the class entirely as you can see. It still does not work. It is like it is not executing get( )
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/weather_model.dart';
import 'package:http/http.dart';
final String weatherURL = 'dfg';
Future<WeatherLocation> getWeatherLocation(Client client) async {
Response res = await client.get(weatherURL);
return compute(parseWeatherLocation, res.body);
}
WeatherLocation parseWeatherLocation(String json){
return WeatherLocation.fromJson(jsonDecode(json));
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<WeatherLocation> _weatherLocation;
@override
void initState() {
super.initState();
_weatherLocation = getWeatherLocation(Client());
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FutureBuilder(
future: _weatherLocation,
builder:
(BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
print("hi");
return Container();
} else {
return Center(child: CircularProgressIndicator());
}
},
));
}
}
@dario-digregorio compute is sugar for isolate which need to take a
top level
orstatic
function I'm not sure that this is the case forparseWeatherLocation
does the code below run?
import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter_app/weather_model.dart'; import 'package:http/http.dart'; class HttpService { final String weatherURL = 'https://api.openweathermap.org/data/2.5/weather?lat=12.8578252&units=metric&lon=66.0999831&appid=<API_KEY>'; Future<WeatherLocation> getWeatherLocation(Client client) async { Response res = await client.get(weatherURL); + return parseWeatherLocation(res.body); - return compute(parseWeatherLocation, res.body); } WeatherLocation parseWeatherLocation(String json){ return WeatherLocation.fromJson(jsonDecode(json)); } }
also it's always useful to provide an actually runnable code (I'm referring to the unusable
weatherURL
) otherwise the issue will be hardly workable@Mashood97 you bested me on the line 🥇
It does not run. You are passing the function call parseWeatherLocation
as parameter of parseWeatherLocation()
. Is there a typo?
@dario-digregorio I've edited my previous post to make my point more clear, regardless it seems to me that http works just fine as for the code below and anyway if the problem was actually http package the issue should have been opened here
if the issue persist w/o compute
it very likely depends from the api or how the authentication is handled
Basically since the res.body
would sometimes return null the Future will return a null and therefore at the check snapshot.hasData
never build the other widget. By checking the statusCode of the response the method would only return a initialized value.
Future<WeatherLocation> getWeatherLocation(Client client) async {
Response res = await client.get(weatherURL);
if (res.statusCode == 200) {
return compute(parseWeatherLocation, res.body);
}
}
I will close the issue.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v
and a minimal reproduction of the issue.
Steps to Reproduce
flutter create bug
.void main() { runApp(MyApp()); }
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title;
@override _MyHomePageState createState() => _MyHomePageState(); }
class _MyHomePageState extends State {
final HttpService _httpService = HttpService();
Future _weatherLocation;
@override void initState() { super.initState(); _weatherLocation = _httpService.getWeatherLocation(Client()); }
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: FutureBuilder( future: _weatherLocation, builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasData) { print("hi"); return Container(); } else { return Center(child: CircularProgressIndicator()); } }, )); } }
pubspec.yaml
weather_model.dart which I generated with an online tool
class WeatherLocation { double lat; double lon; String timezone; int timezoneOffset; Current current; List3.Just run the application and see that the Future never completes. I just followed the instruction on flutter.dev and wanted to try out the openweatherapi.
Expected results: The Future should complete and the CircularProgressIndicator should go away. Also the console should print 'hi' but it never does.
Actual results: CircularProgressIndicator is spinning forever. Nevertheless I can type in any url and it never completes. Not even an error. If I return the response instead so I dont parse anything the Future completes instead. But the parsing function is just a synchronized job so I am not sure what really produce this strange behavior. But since it is so easy to reproduce I created an Issue.
Console output
Flutter Analyze
Flutter Doctor