Electron+React+Typescriptでお天気アプリを作る


Electron+React+Typescriptの開発環境を作るの続編として、OpenWeatherMapを使って簡単なお天気アプリを作成しようと思います。

API Key取得まで

API Key取得までは無料天気予報APIのOpenWeatherMapを使ってみるを参考にしてください。

お天気アプリ作成

今回作るアプリは下記のWebアプリです。

コードはhttps://github.com/butachin/Weather-App に書いてあります。

Componentの作成

今回は上記でお見せしたような1つ1つのデータに対してカード(WeatherCard)を作成し、それをリスト(WeatherCardList)として表示するアプリを作成します。reduxは使わないので手をつけやすいと思います。

WeatherCard


PostmanでAPIを叩くと下記のような画面が現われるので、ここで基本をhttp://api.openweathermap.org//data/2.5 として調べたい市と自分のAPIKeyを設定する。そうするとデータが返ってくるのでそれを今回のモデルとして反映する。

src/components/WeatharCard/WeatherCardProps.ts
export interface IWeatherCard {
    dt: number;
    main: {
      temp: number;
      temp_min: number;
      temp_max: number;
      pressure: number;
      sea_level: number;
      grnd_level: number;
      humidity: number;
      temp_kf: number;
    };
    weather: [
      {
        id: number;
        main: string;
        description: string;
        icon: string;
      }
    ];
    clouds: {
      all: number;
    };
    wind: {
      speed: number;
      deg: number;
    };
    sys?: {
      pod: string;
    };
    dt_txt: string;
  }

interfaceとしてモデルを定義する。

src/components/WeatherCard/WeatherCard.tsx
import * as React from "react";
import { Card, Avatar } from "antd";
import { IWeatherCard } from './WeatherCardProps';

const { Meta } = Card;

class WeatherCard extends React.Component<IWeatherCard, any> {
  constructor(props: any) {
    super(props);
  }

  private kelvinToCelsius = (temp: number): number => Math.round(temp - 273.15);

  public render() {
    return (
      <div>
        <Card className="Card">
          <Meta
            avatar={<Avatar src={`http://openweathermap.org/img/w/${this.props.weather[0].icon}.png`}size="large"/>}
            title={
              <div>
                <p>{this.props.weather[0].main}</p>
                <h3>{this.kelvinToCelsius(this.props.main.temp) + "°C"}</h3>
              </div>
            }
            description={this.props.dt_txt}
          />
        </Card>
      </div>
    );
  }
}

export default WeatherCard;

antdというDesign Componentを使い受け取ったデータをCardとして配置する。

src/components/WeatherCardList/WeatherCardList.tsx
import * as React from "react";
import * as request from "superagent";
import { IWeatherCard } from '../WeatherCard/WeatherCardProps';
import WeatherCard from '../WeatherCard/WeatherCard';

interface IWeatherCardList {
  weatherCards: IWeatherCard[];
}

class WeatherCardList extends React.Component<any, IWeatherCardList> {
  constructor(props: any) {
    super(props);
    this.state = {
      weatherCards: []
    };
  }

  public componentWillMount() {
    request
      .get("http://api.openweathermap.org/data/2.5/forecast")
      .query({
        q: "Hakodate",
        appid: "APIKey"
      })
      .then(response => response.body.list)
      .then(body => {
        console.log(body);
        this.setState({
          weatherCards: body
        });
        console.log(JSON.stringify(this.state.weatherCards));
      })
      .catch(error => {
        console.log(error);
        throw error;
      });
  }
  public render() {
    const resultNodes = this.state.weatherCards.map(weatherCard => {
      return <WeatherCard key={weatherCard.dt} {...weatherCard} />;
    });

    return (
    <div>
        <h1>函館お天気情報</h1>
        <p>Hakodate Weather Information</p>
        <ul>{resultNodes}</ul>
    </div>
    )};
}

export default WeatherCardList;

componentWillMount()を用いてOpenWeatherMapAPIを叩く。その際、superagentというライブラリを使用する。queryとしてqには自分の天気を知りたい市を、appidには自分のAPIKeyを入れる。
あとは、renderでWeatherCardの個数分回してresultNodesに代入したら、それを表示するだけです。

最後に

今回cssについてはあまり触れていません。一応https://github.com/butachin/Weather-App には書いてあるので興味があったら見てください。わかりづらいとは思いますが、こんな感じで簡単にWebアプリが作れます。よかったら参考にしてください。