5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Flutter]httpを使ってAPIと通信する(取得データ活用編)

Posted at

投稿の経緯

今回は以前投稿した、「httpを使ってAPIと通信する(データ取得編)」の続きです。
取得したデータをModelに格納してWidgetでデータを表示したいと思います。

前回の投稿はこちら↓

環境

Flutter version:3.7.3
Dart version:2.19.2
IDE:Android Studio

Modelに取得データを格納する

取得したデータの中から今回必要なweatherの部分をModelに格納します。

response: {
    "lat":35.6514,
    "lon":139.6367,
    "timezone":"Asia/Tokyo",
    "timezone_offset":32400,
    "current":{
        "dt":1678618031,
        "sunrise":1678568265,
        "sunset":1678610717,
        "temp":288.71,
        "feels_like":288.12,
        "pressure":1022,
        "humidity":69,
        "dew_point":283.05,
        "uvi":0,
        "clouds":75,
        "visibility":10000,
        "wind_speed":4.63,
        "wind_deg":160,

        // 'weather'のデータを格納する
        "weather":[
            {
                "id":803,
                "main":"Clouds",
                "description":"曇りがち",
                "icon":"04n"
            }
        ]
    }
}

Modelクラスを作成します。

.dart
class WeatherModel {
  final String main;
  final String description;
  final String icon;

  WeatherModel({
    required this.main,
    required this.description,
    required this.icon
  });

  factory WeatherModel.fromJson(Map<String, dynamic> json) {
    var weather = json['weather'];
    var data = weather[0];

    var model = WeatherModel(
        main: data['main'],
        description: data['description'],
        icon: data['icon']
    );

    return model;
  }
}

.fromJsonでMap<String, dynamic>型のjsonを受け取ってWeatherModel内でデータを格納するように書きました。呼び出し元の関数は以下の通り。

.dart
Future<WeatherModel?>get() async {
    const lat = '35.65138';
    const lon = '139.63670';
    const key = 'aa50ce0598c22de20f75cf3ea31ac312';

    const domain = 'https://api.openweathermap.org';
    const pass = '/data/2.5/onecall';
    const query = '?lat=$lat&lon=$lon&exclude=daily&lang=ja&appid=$key';

    var url = Uri.parse(domain + pass + query);
    debugPrint('url: $url');

    var response = await http.get(url);

    if (response.statusCode == 200) {
      var body = response.body;
      var decodeData = jsonDecode(body);
      var json = decodeData['current'];
      var model = WeatherModel.fromJson(json);

      return model;
    }
    return null;
}

レスポンスのデータにアクセスするためにjsonDecodeしたデータをWeatherModel.fromJsonに渡し、Future<WeatherModel?>型でModelを返しています。

次は作成したModelを使ってWidgetを構築していきます。

ModelのデータでWidgetを構築する

APIと通信して、取得したデータをモデルに格納する一連のコードは非同期でおこなわれているので、Widgetの構築にはFutureBuilderを使ってみます。

FutureBuilderとは

「Future = 非同期処理」の結果を受けてWidgetを構築する仕組みです。(便利!)

.dart
FutureBuilder(
    future: , // 何かしらの非同期処理
    builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.hasData) {
            // 処理終了後に呼ばれる
        } else {
            // 処理中に呼ばれる
        }
    }
);

非同期で終了を待ちたい処理をfutureに、その結果を受けてWidgetを構築する処理をbuilderに定義します。builderにはBuildContextAsyncSnapshotの2つの引数が必要です。

この内、AsyncSnapshotにfutureで指定した非同期処理の結果が入るので、そのデータを使ってWidgetを構築します。ちなみにAsyncSnapshotには型を指定することもできます。

処理終了/処理中 なのかはsnapshot.hasDataで判断できます。
「true = 処理終了」「false = 処理中」といった状態です。非同期処理が終了しているとsnapshot.dataから結果にアクセスでき、そのデータを使ってWidgetを構築します。

注意点はhasDataのtrue/falseの両方にWidgetを構築する必要があるということです。

実際に使ってみた

.dart
@override
Widget build(BuildContext context) {
  return FutureBuilder(
      future: get(),
      builder: (BuildContext context, AsyncSnapshot<WeatherModel?> snapshot) {
        if (snapshot.hasData) {
          var data = snapshot.data;

          return Scaffold(
            body: Center(
                child: Text('現在の天気は${data?.description}です!')
            )
          );
        } else {
          return const Scaffold(
              body: Center(
                  child: Text('処理中...')
              )
          );
        }
      }
    );
  }
}

非同期処理中は「処理中...」と表示され、処理終了後はAPIから取得した天気情報が表示されるシンプルな画面です。

実際の動作

AnyConv.com__動作確認 (1).gif

このように非同期処理の処理中/処理終了でWidgetを自動で切り替えてくれるFutureBuilderは便利ですね!

おわりに

前回の記事と合わせたここまでの実装で

httpでAPIと通信して

取得データをModelに格納して

Modelを使ってWidgetを構築

といった一連の流れはできたかなと思います。

引き続きFlutterに関する学びを発信していきます。最後までご覧いただきありがとうございました!

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?