I’m new to Flutter and trying to get data from an API. I can’t call my Method from another class even its imported. I’m trying to call that specific method in weather_page.dart from weather_service.dart. Can you help me?
weather_service.dart
import 'dart:convert';
import 'package:testapp/models/weather_model.dart';
import 'package:http/http.dart' as http;
class WeatherService {
//static const BASE_URL = 'https://api.openweathermap.org/data/2.5/forecast?q=Kutahya,tr&cnt=5&appid=e6080829dff63e16ef3e9756b2e4b0bd';
static const baseUrl = 'https://api.openweathermap.org/data/2.5/weather?';
final String apiKey; //The “final” keyword is used to declare variables whose values cannot be changed once assigned. When a variable is declared as final, it can only be assigned a value once, either at its declaration or within the constructor of the class.
WeatherService(this.apiKey){
Future<Weather> getWeather(String city, String country) async {
final response = await http.get(Uri.parse('$baseUrl?q=$city,$country&appid=$apiKey&units=metric'));
if (response.statusCode == 200) {
return Weather.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to get Data');
}
}
}
}
weather_page.dart
import 'package:flutter/material.dart';
import 'package:testapp/models/weather_model.dart';
import 'package:testapp/services/weather_service.dart';
class WeatherPage extends StatefulWidget {
const WeatherPage({super.key});
@override
State<WeatherPage> createState() => _WeatherPageState();
}
class _WeatherPageState extends State<WeatherPage> {
//set api key
final _weatherService = WeatherService('e6080829dff63e16ef3e9756b2e4b0bd');
Weather? _weather; //imported from models/weather_model
//set city and country
String city = 'Kutahya'; //You may use Geolocator to get them automatically also.
String country = 'tr';
//get data
_fetchWeather() async {
try {
final weather = await _weatherService.getWeather(city, country);
setState(() {
_weather = weather;
});
}
catch (e){
print(e);
}
}
@override
Widget build(BuildContext context) {
return const Scaffold();
}
}
I have tried to call variable named apiKey from weather_service.dart and it works. I suppose its imported correctly, maybe something wrong about my method. Thanks for answers.
1
You can fix by doing this
class WeatherService {
//static const BASE_URL = 'https://api.openweathermap.org/data/2.5/forecast?q=Kutahya,tr&cnt=5&appid=e6080829dff63e16ef3e9756b2e4b0bd';
static const baseUrl = 'https://api.openweathermap.org/data/2.5/weather?';
final String apiKey;
WeatherService({required this.apiKey});
Future<Map<String, dynamic>> getWeather(String city, String country) async {
final response = await http.get(Uri.parse('$baseUrl?q=$city,$country&appid=$apiKey&units=metric'));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to get Data');
}
}
}
Your code looks great, but the mistake you made is calling your getWeather function in the constructor. To use this function, you should call it outside of the constructor. That way, you can use the function properly
class DemoClass {
String yourKey;
// Constructor
DemoClass(this.yourKey);
// Outside of the constructor
Future<String> yourFunction() async {
return "Your API response";
}
}
I would also suggest using proper state management to achieve performance improvements in your application.
Try below code hope its help to you.
WeatherService
class WeatherService {
static const baseUrl = 'https://api.openweathermap.org/data/2.5/forecast';
final String apiKey;
WeatherService(this.apiKey);
Future<WeatherModel> getWeather(String city, String country) async {
final response = await http.get(
Uri.parse('$baseUrl?q=$city,$country&appid=$apiKey&units=metric'),
);
if (response.statusCode == 200) {
return WeatherModel.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to get Data');
}
}
}
WeatherPage
class WeatherPage extends StatefulWidget {
const WeatherPage({super.key});
@override
State<WeatherPage> createState() => _WeatherPageState();
}
class _WeatherPageState extends State<WeatherPage> {
final WeatherService weatherService = WeatherService('e6080829dff63e16ef3e9756b2e4b0bd');
WeatherModel? weather;
WeatherModel? fetchedWeather;
bool isLoading = false;
String errorMessage = '';
//set city and country
String city = 'Kutahya'; //You may use Geolocator to get them automatically also.
String country = 'tr';
@override
void initState() {
super.initState();
fetchWeatherData();
}
Future<void> fetchWeatherData() async {
setState(() {
isLoading = true;
errorMessage = '';
});
try {
fetchedWeather = await weatherService.getWeather(city, country);
setState(() {
weather = fetchedWeather!;
});
} catch (error) {
setState(() {
errorMessage = 'Failed to load weather data: $error';
});
} finally {
setState(() {
isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Weather')),
body: isLoading
? Center(child: CircularProgressIndicator())
: errorMessage.isNotEmpty
? Center(child: Text(errorMessage))
: weather != null
? Center(
child: ListView.builder(
itemCount: weather!.list!.length,
itemBuilder: (context, index) {
return Text(weather!
.list![index].weather![0].description
.toString());
},
),
)
: Center(child: Text('No weather data')),
);
}
}
I have try some Data on UI:
weather_service.dart
place getWeather method outside the constructor
import 'dart:convert';
import 'package:testapp/models/weather_model.dart';
import 'package:http/http.dart' as http;
class WeatherService {
//static const BASE_URL = 'https://api.openweathermap.org/data/2.5/forecast?q=Kutahya,tr&cnt=5&appid=e6080829dff63e16ef3e9756b2e4b0bd';
static const baseUrl = 'https://api.openweathermap.org/data/2.5/weather?';
final String apiKey; //The “final” keyword is used to declare variables whose values cannot be changed once assigned. When a variable is declared as final, it can only be assigned a value once, either at its declaration or within the constructor of the class.
WeatherService(this.apiKey);
Future<Weather> getWeather(String city, String country) async {
final response = await http.get(Uri.parse('$baseUrl?q=$city,$country&appid=$apiKey&units=metric'));
if (response.statusCode == 200) {
return Weather.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to get Data');
}
}
}
call _featchWeather() inside initState()
weather_page.dart
@override
void initState(){
super.initState();
_fetchWeather();
}
_fetchWeather() async{
try{
final weather = await _weatherService.getWeather(city,country);
setState((){
_weather = weather;
});
}
catch(e){
print(e);
}
}
Akshay payya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.