skip to Main Content

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.

4

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');
        }
      }
    }
    
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
  3. 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:

    image

    Login or Signup to reply.
  4. 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);
    }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search