---
# System prepended metadata

title: 即時天氣APP 實作
tags: [實作, AJAX]

---

# 即時天氣APP 實作

###### tags: `實作` `AJAX`

[實作頁面連結](https://allenw0815.github.io/mission/mission_32/index.html)

![](https://i.imgur.com/enrXXF8.png)


### Flowchart

1. 到氣象局網站取得授權 API
2. 寫 HTML 結構，這邊只需要先做一個公版樣式
3. 寫 CSS 
4. AJAX 拿資料
5. 依照結構去帶入相對資料後 render 到畫面中

> JS 流程

1. 取資料
```javascript=
let latestData = null

const getDateAJAX = () => {
    fetch(url)
    .then((res)=>{
       return res.json()
    })
    .then((result)=>{
        latestData = result.records.locations[0].location        
        let cityIndex = 0
        setOption(cityIndex)// 依照資料筆數設定 select 的項目
    })
}
```

2. 依照資料筆數設定 select 的項目
```javascript=
const setOption = (cityIndex) =>{
    let display = ''
    for(let i = 0 ; i < latestData.length ; i++){
        display += 
        `
        <option value="${i}">${latestData[i].locationName}</option>
        `      
    }
    select.innerHTML = display
    changeCity(cityIndex)
}
```

3. 選不同的 option 時會指派給 cityIndex 不同的值進而改變畫面 ( 預設為 0 ) 在載入時會先執行一次 ， 所以顯示"雲林的資料"
```javascript=
const changeCity = (cityIndex) =>{
    cityIndex = select.value
    showCards(latestData,cityIndex)
    showMainCard(latestData,cityIndex)
}
```

4. 生成畫面，我分別用兩個 fuction 生成 (因為樣式不同)，這是其中一個依照資料生成畫面的 function ，把畫面需要的每一種資料都變成一個陣列 ex : ["多雲", "多雲", "多雲", "晴時多雲", "晴時多雲", "多雲時晴"]，然後按照順序生畫面。
```javascript=
const showCards = (latestData,cityIndex) =>{
    let unhandleData = latestData[cityIndex]
    let city = latestData[cityIndex].locationName
    let time = timeHandler(unhandleData)
    let temperature = temperatureHandler(unhandleData)
    let weather = weatherHandler(unhandleData)
    let weatherImg = setWeatherImgArray(weather)
    let bodyTemperature = bodyTemperatureHandler(unhandleData)
    let rainProbability = rainProbabilityHandler(unhandleData)
    let humidity = humidityHandler(unhandleData)
    let display = ''
    for(let i = 0 ; i < 6 ; i++ ){
        display +=
        `
        <div class="card">
        <h2>${city}</h2>
        <h3>${time[i]}</h3>
        <div class="weather-temp">
        <img src=${weatherImg[i]} alt="" />
        <h3>${temperature[i]}°C</h3>
        </div>
        <div class="info">
        <table>
            <thead>
            <tr>
                <th colspan="2">天氣資訊</th>
            </tr>
            </thead>
            <tbody>
            <tr>
                <td>天氣現象</td>
                <td>${weather[i]}</td>
            </tr>
            <tr>
                <td>體感溫度</td>
                <td>${bodyTemperature[i]}°C</td>
            </tr>
            <tr>
                <td>降雨機率</td>
                <td>${rainProbability[i] === ' ' ? '未測出' : rainProbability[i]+'%'}</td>
            </tr>
            <tr>
                <td>相對溼度</td>
                <td>${humidity[i]}%</td>
            </tr>
            </tbody>
        </table>
        </div>
        </div>
        `
    }   
    cards.innerHTML = display
}
```
### 記錄

> 不論是天氣資訊、Google 地圖、Instagram 或 Facebook 等許多第三方的 API 服務，都不會讓你「匿名」使用，因此多數都會需要你先註冊後，才會發給你一組「金鑰（Key）」，之後所有對該服務所發送的請求都需要附帶上這組金鑰，這些服務的供應者就可以透過此把金鑰來辨認你使用他們服務的頻率和情況。

> 一開始 AJAX 拿到資料後我一直往下層的 fuction 傳進去使用，但是到了 selcet 的 change 觸發的時候也會呼叫 changeCity() 就會沒辦法拿到資料，所以後續的變數都變成 undefined
>>*  應該取得資料後存在全域(或是拿的到的地方就行)

> 原本使用的資料一些用傳入參數一些用另存的 latestData 這樣資料流是亂的
>>* 統一使用另存的資料就好

* 大哥的解說
![](https://i.imgur.com/Aw1kVJk.png)



### 小記

之前課程很少時做 AJAX 串接的部分，相對的資料處理也很生疏，對我來說是個很好的練習。
大概寫了一天多兩天左右，應該都是會的東西，但是會因為一些大大小小的問題卡著，做的不順。
可以再補充的部分

* RWD
> 在第一次 call AJAX 的時候可以記錄當下時間
  當使用者切換縣市的時候判斷時間是否超過一定時間
  是的話就要在次 call 一次 AJAX 更新資料

### 參考

[氣象資料開放平台](https://opendata.cwb.gov.tw/index)
[天氣因子中文對照表](https://opendata.cwb.gov.tw/opendatadoc/MFC/D0047.pdf)