---
# System prepended metadata

title: 4/13 線上 Slack 助教
tags: [JS 直播班 - 2021 春季班]

---

---
tags: JS 直播班 - 2021 春季班
---

# 4/13 線上 Slack 助教

## 今日輪班助教時間

hsin-yu：4/13（二）
早上 10:00 - 中午 12:00，下午 1:00 -下午 5:00


## 發問規範

老師助教同學們好，**這是我的 Codepen**，我**原本預期**「JS 第 8 行會出現數字 8」，**但卻出現**「預期外的結果是 0」，想問下問題出在哪裡？

## 注意

1. 請各位先到 Slack 上將問題放在助教服務內的 thread，如圖
 ![](https://i.imgur.com/nHE3sOx.png)
2. 遵循以上的發問規範以便助教查看問題，不可直接貼上網址而沒有說明文字或者只提供截圖
3. 助教會依照 Slack 上的順序回覆問題
4. 以下問題區塊只能由助教自行增加
5. 助教會將回覆寫在下方問題區塊

## 問題

1. **Carrie：**
老師助教同學們好，這是我的 [CodePen](https://codepen.io/echocarriet/pen/yLgKBGL)
我原本預期「JS 第 18 ~ 26 行」saveBtn 監聽事件會先執行驗證的函式：renderValidate()，驗證成功就會執行 addItem()，卻出現 「不論 input 欄位是否有符合規則，都會顯示 let constraints 中設定的錯誤訊息 」，而且點選 " 新增按鈕 " 似乎都要點選兩次才會顯示錯誤訊息。
不知道哪邊觀念出了問題，想請問 saveBtn 監聽事件內要怎麼驗證 renderValidate()，驗證成功再執行 addItem() 新增資料呢，冏 ?
再麻煩指引，謝謝助教 !
> 助教回覆：
> 更新：需要點兩次「新增按鈕」才會顯示錯誤訊息可能是因監聽按鈕及驗證的部分（第 101 - 111 行）是放在 inputs.forEach() 中，因此會對同一個按鈕綁定兩次點擊事件
> 不論 input 欄位是否填寫都會出現 error 可能是因在第 95 行宣告 error（在未填寫表單時就驗證因此都會出現錯誤訊息），如果是在觸發 click 事件後才宣告 error，就會是正確的驗證
> 更新：
原本有建議可以改成對 inputs 監聽 change 事件，但是對「新增」按鈕監聽 click 事件驗證表單也是可以的，這裡附上改寫[範例](https://codepen.io/tina2793778/pen/wvgmdYY?editors=0011)（88 - 109 行），可以參考後改改看 ，如果有不清楚的地方歡迎再提問～

---

2. **周周：**

老師助教同學們好，這是我的 Codepen，我原本預期「執行完按鈕後應該會出現必填」，但卻出現「執行完畫面就清空了」，想問下問題出在哪裡？
> 助教回覆：
> 這裡測試點擊「送出訂單」按鈕後會出現必填，不過需在 submitBtn 監聽 click 事件時執行 e.preventDefault() 阻止預設行為，因 submitBtn 是  `<input type="submit">` ，預設會執行送出表單資料並跳至另一個頁面的行為，但是我們希望可以在點擊時執行其他行為，因此需先執行 e.preventDefault() 阻止原本的預設行為
或是將「送出訂單」按鈕改成 button，並將 type 設定為 button，就不會有預設的行為

3. **youting：**
老師助教同學好，4/13的每日任務解答 https://codepen.io/znlcgmgk/pen/JjEOxby?editors=1011 第14 行 getCategories(productData); 呼叫時有傳參數，但第 62 行宣告時卻沒有預設參數，而是使用全域的 productData 去處理，請問是有什麼用意嗎？還是宣告時會預設但不一定會傳參數
> 助教回覆：
> 因第 62 行宣告 getCategories function 時沒有預設參數，因此應該都是使用全域的 productData，第 14 行的 getCategories() 沒有傳入參數也可以正常執行 ，沒有使用到參數的部分
這裡會再另外和助教確認再更新回覆喔～
> 更新：這裡有和助教確認過，不需傳遞參數喔（範例也有修改了，感謝同學的回報！

---
4. **雅帆：**
老師助教同學們好，這是我的 [Codepen](https://codepen.io/yafanchung/pen/qBRxqKj?editors=1011)，我原本預期「JS 第 56-67 行的結果會出現 areaTotal 的新物件，像這樣 areaTotal = {台北 = 1,台中=2} 的資料格式，可是 console 出來卻沒有出現此資料格式，再請幫我看下我是哪邊有些錯，謝謝
我是參考老師的[範例](https://codepen.io/hexschool/pen/VwPwRyd?editors=0010)的 JS 第 11-20 行
> 助教回覆：
> 這裏 function 中的寫法是沒問題的，但是少了呼叫 function 的步驟，可以在 init() 中拿到 data 後呼叫 renderC3() 
這裏呼叫 function 後是有印出 areaTotal 的，可以再嘗試看看～

---

5. **Alysa Chan：**
老師助教同學們好，請問如果要隱藏API key以及uid這兩個機密資料，是不是只能在node.js或後端處理呢？目前自己理解的方法，一是在 node.js 搭配dotenv插件使用.env環境變數的方法，二是在node.js使用proxy server。但這些都是後端的部分，那麼前端，不論是Vue/React/Angular框架，還是原生JS，是否也有方法隱藏機密資料？還是只能在後端才做到？
因為最終作業有用到API key以及 uid，但目前我的做法是直接寫在js檔案裏，也就是公開暴露這些資料，但我理解這是一個很高風險的做法，所以想請教實務上應有的做法，謝謝！
> 助教回覆：
> 如果要存前端的話，~~可放在 session 做加密~~，但最好的方法還是在後端用～
> **更正**：應該是存在 cookie，不是 session，但是如果存在 cookie 也是登入後才去取得

---
6. **雅帆：**
這是我的 [Codepen](https://codepen.io/yafanchung/pen/qBRxqKj?editors=1011)，想請問 JS 40 行宣告 let data = []; ，在 init function 內將 data 賦予值 res.data.data; ，我想請問為什麼  console.log(data) 要在 function 裡面才撈的到值，在 function 外面( JS 52 行) 會撈不到值呢?
是因為雖然 data 的空陣列是在 function 外面宣告，可是賦予值是在 function 裡面，所以當執行完函式後  data = res.data.data; 就會隨著函式消失，只剩下 let data = []; ?
再請助教解惑，感謝><
> 助教回覆：
> 這裡是因使用 axios 發送 request 是非同步的，代表第 42 行 axios 的部分是發送 request 後就不管它了，先繼續執行後面的程式，等到接收到 response 後才會重新賦予 data 值，除了 axios 的其他部分都會在載入畫面時就依序一行一行執行
因此執行順序會是先執行第 52 行的 console.log(data)，接收到 response 後才會執行到 data = res.data.data;，所以第 52 行印出的 data 是還沒重新賦予值的 data
觀察 console.log 的印出的順序也會發現先印出空陣列，才印出「資料有回傳了」以及 response 內容，代表會先執行同步的程式，接收到 response 後才會執行 .then() 裡面的程式


---
7. **Valerie：**
老師助教同學們好，這是我的 [Codepen](https://codepen.io/vicky-chang/pen/oNBBRBb?editors=0110)，我原本預期「JS 第 190 - 200 行能夠執行驗證」，但卻沒有出現驗證，想問問題出在哪裡？謝謝!
> 助教回覆：
> 第 190 - 200 行可以不需要，因 formValid 函式沒有預設參數，也沒有回傳特定的內容（function 若沒有寫 retrurn xxx，預設會回傳 undefined），因此 190 - 200 行不會符合條件，因 formValid() 會是 undefined
> 296 - 301 行會判斷若 errors 有值（代表驗證後欄位有填寫錯誤產生錯誤訊息），會將錯誤訊息渲染到畫面上
可以接著判斷 else ，執行如果沒有錯誤的程式，這時候在原本 190 行的位置就可以判斷如果沒有錯誤就新增套票（或是如果有錯誤就 return）
另外 第 288 行選取 DOM 沒有選取到 select，景點地區的 select 沒有被驗證到～ 

---

8. **Page Shih：**
老師助教同學們好，這是我的 [Codepen](https://codepen.io/kanawin821/pen/RwKMevx)（請附上連結），我原本預期「輸入文字後按送出表單，console.log的物件會有值」，但卻出現「網頁卻跑出Not found，物件裡也沒有填上值」，想問下問題出在哪裡？
> 助教回覆：
> 因 `<input type="submit">` 預設會點擊時執行送出表單的行為，可以參考這篇[文章](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/submit)，有提到 「當 click 事件發生時（通常是因為用戶單擊了按鈕）， 用戶代理嘗試將表單提交給服務器」
> 如果要在點擊後執行其他動作，需要在觸發點擊事件後的 function 先執行 e.preventDefault() 取消預設行為（e 是參數可以自訂），詳細寫法可以參考 [Event.preventDefault() - Web APIs | MDN](https://developer.mozilla.org/zh-TW/docs/Web/API/Event/preventDefault) ，取消預設行為後就可以正確執行新增 data 了
> 或是將  `<input type="submit">` 改為 button，並將 type 設定為 button，就不會有預設行為



（這裡只能由助教自行增加問題，請大家將問題放在 thread 上）






