---
tags: Node.js 直播班 - 2022 春季班
---
# Node.js 直播班每日任務
第一週
---
- 4/8 每日任務 Day1:[非同步概念、建立 Promise](https://hackmd.io/AMXBRw3jR22p9NC0a4jItA)
- 4/11 每日任務 Day2:[非同步概念、使用 Promise](https://hackmd.io/OJDzSoL7R-6JdRbHCRKZPQ)
- 4/12 每日任務 Day3:[MongoDB 基本操作: 新增、查詢](https://hackmd.io/TgtMJ7rVSzqVkua1gZu_DQ)
- 4/13 每日任務 Day4:[MongoDB 基本操作: 修改、刪除](https://hackmd.io/P7NQzc9uSX2syvol-56mBQ)
- 4/14 每日任務 Day5:[非同步概念、async await](https://hackmd.io/iiQw7hA3TUOzm-eZPewUgg)
第二週
---
- 4/15 每日任務 Day6:[schema、mongoose](https://hackmd.io/MGSN1-xOSBWvFx2FSMYVAg)
- 4/18 每日任務 Day7:[model、Mongoose 新增 / 查詢](https://hackmd.io/lX0yu-6KRD2rdX-K0cQnCA)
- 4/19 每日任務 Day8:[schema 補充](https://hackmd.io/T8aLkLT6SjiEh_dQLrxl2w)
- 4/20 每日任務 Day9:[Mongoose 修改 / 刪除](https://hackmd.io/B8e884-cSK6zYsgb7FOIUg)
- 4/21 每日任務 Day10:[拆分 Model](https://hackmd.io/dM6fOkJgQe-9-ixsWmKqhg)
第三週
---
- 4/22 每日任務 Day11:[Express 安裝](https://hackmd.io/8NCCRsluSFSSaJct8Kbn8A)
- 4/25 每日任務 Day12:[設計基本路由](https://hackmd.io/4xtwDtcwTr6yv6m-WGMnTw)
- 4/26 每日任務 Day13:[express 應用程式產生器、在 routes 設計路由](https://hackmd.io/H9FOdWreRGeT8uy3yYDhHA)
- 4/27 每日任務 Day14:[req.query 篩選網址參數](https://hackmd.io/EQ3Po0mDRS-V91wf8zlBBg)
- 4/28 每日任務 Day15:[req.body 新增資料](https://hackmd.io/tFqX3zZTSq-pazcm7N_Lbw)
第四週
---
- 4/29 每日任務 Day16:[req.params 取得特定資料](https://hackmd.io/wq0Y4d2zTOWdzUIklRHl6Q)
- 5/2 每日任務 Day17:[學習時間、方法、進度 分享](https://hackmd.io/gxbAZF8DSwWaR7fNpofn7Q)
- 5/3 每日任務 Day18:[Mongoose - Populate](https://hackmd.io/gOkRAVKcSWu0tUz5mVcGSA)
- 5/4 每日任務 Day19:[取得資料搭配 sort()、limit()](https://hackmd.io/vprxhH04TR-ASFXgAHIaAQ)
- 5/5 每日任務 Day20:[Middleware](https://hackmd.io/Yp0a--8xRwW9LAezQaam-A)
<!-- * 4/25:[設計基本路由,可依照最終作業設計稿的頁數來設計](https://expressjs.com/zh-tw/starter/basic-routing.html)
* 4/26:[express 產生器(選擇 no view ,因為我們沒有 view 只回傳 JSON),並設計新 router,/user/,新增與修改個人資料](https://expressjs.com/zh-tw/starter/generator.html)
* 4/27:練習 req.query 篩選網址參數資料教學
* 4/28:依照 Adobe XD 設計稿,透過 POST API 的 req.body 新增一則貼文,可提供 GitHub 寫一半的範本,並讓他們提交 GitHub Repo,並同時可寫說,請他們要做欄位資料驗證 -->
<!-- * 4/29:使用 req.params 取得 :id,例如當對方輸入這個[網址](https://www.facebook.com/sfismy/posts/5281803261839276)時,可以 response 該特定貼文資料,這必須整合 mongoose
* 5/2:輕鬆一下,分享平常都何時在練習,簽到目前都在第幾關、需要可以做到什麼程度
* 5/3:(做成像是語法填空),練習 populate 設計一個情境,書本與作者的 collection,然後顯示單一書本的內容時,可以 populate user 的資料
* 5/4:練習 find() 以後,去接 sort 的時間排序、limit 限制幾筆資料
* 5/5:講解 middleware (會釋出影音課程) -->
第五週
---
- 5/6 每日任務 Day21:[HTTP 狀態碼](https://hackmd.io/pe9-iKTxRti2TKXpE7NyoA)
- 5/9 每日任務 Day22:[uncaughtException、unhandledRejection](https://hackmd.io/xmSNXfGbQdOTniA_fpS0Yg)
- 5/10 每日任務 Day23:[自訂錯誤訊息](https://hackmd.io/cJyEKvpeTfKJ6dcF3K9sNA)
- 5/11 每日任務 Day24:[development 及 production 環境變數指令、客製錯誤訊息](https://hackmd.io/FSs4tjRtQqy8jnXnfcLdCw)
- 5/12 每日任務 Day25:[非同步錯誤管理](https://hackmd.io/4p9tSRDcTtGVc6Ya0pbBzA)
<!-- * 5/6:出選擇題,提供幾個情境,詢問 [HTTP 狀態碼](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Status)該回傳 200、201、400、401、404、500 等等
- 講解 [handleErrorAsync](https://github.com/hexschool/mongoose-post/blob/main/week5-midtermExam/utils/handleErrorAsync.js),題目:將 handleErrorAsync 加入 [router](https://github.com/hexschool/mongoose-post/blob/main/week5-midtermExam/routes/posts.js#L8-L27)
- [appError](https://github.com/hexschool/mongoose-post/blob/main/week5-midtermExam/utils/appError.js) 介紹,在 controllers 加入可預期錯誤
- 設定環境變數執行指令分出 development、production 模式,題目:嘗試客製化兩者模式的回饋訊息
```javascript
// error handler
app.use(function(err, req, res, next) {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
if (process.env.NODE_ENV === 'dev') {
console.log('dev');
resErrorDev(err, res);
} else if (process.env.NODE_ENV === 'prod') {
if(err.isAxiosError== true){
err.message = "axios 連線錯誤";
err.isOperational = true;
return resErrorProd(err, res)
}else if (err.name === 'ValidationError'){
// mongoose 資料辨識錯誤
err.isOperational = true;
return resErrorProd(err, res)
}
resErrorProd(err, res)
}
});
```
- node.js uncaughtException、unhandledRejection 介紹,將有程式錯誤的 app.js 加上 uncaughtException、unhandledRejection,執行時須正確觸發錯誤 -->
第六週
---
- 5/13 每日任務 Day26:[bcrypt.js 密碼加解密](https://hackmd.io/67Pf-ihEQ-SbsHAz0sYvEA)
- 5/16 每日任務 Day27:[validator 驗證](https://hackmd.io/9daPlLQWQ1iAoTptHTekgA)
- 5/17 每日任務 Day28:[JWT 產生身份驗證 token](https://hackmd.io/nV3gymAVTvuqYECcQTU-wg)
- 5/18 每日任務 Day29:[登入功能](https://hackmd.io/TsgmHgmzRfWqT048hRHMEg)
- 5/19 每日任務 Day30:[JWT 驗證](https://hackmd.io/gC52vOSmRz2_BtW0i-RzBA)
- 5/20 每日任務 Day31:[JWT 驗證 middleware](https://hackmd.io/jZz5qcDLQb2wJ36hEA0v0A)
- 5/23 每日任務 Day32:[實作重設密碼](https://hackmd.io/BYirgWM9QRqLK24cmP6agQ)
第七週
---
- 5/24 每日任務 Day33:[multer 處理上傳檔案](https://hackmd.io/yZB0FMW8SxiF0XlTaGMmxg)
- 5/25 每日任務 Day34:[Imgur 串接](https://hackmd.io/7BaSIlheSi-8SyKjAF0R3w)
第八週
---
- 5/26 每日任務 Day35:[取得按讚貼文列表](https://hackmd.io/s8p9adD9SqitPqomeIEJtg)
- 5/27 每日任務 Day36:[新增、取消特定貼文讚](https://hackmd.io/SlgH_tFDQjuHuhzp2NtUYg)
- 5/30 每日任務 Day37:[資料庫設計 embedded / references](https://hackmd.io/Kb-eM0ILQw2g55HoYPjnBQ)
- 5/31 每日任務 Day38:[常見資料庫設計](https://hackmd.io/5OrfXagqSf6abjcJetx4DQ)
- 6/1 每日任務 Day39:[追蹤 / 取消追蹤使用者功能](https://hackmd.io/D8KZubDcQEypx0r_izXflA)
- 6/2 每日任務 Day40:[新增貼文留言功能](https://hackmd.io/jam5zo8pQYennLyiOSPh6g)
- 6/3 每日任務 Day41:[取得所有貼文,加上 comment](https://hackmd.io/YVAJRCAdTS-l7uAtePjeOg)
---
<!-- **第六週大綱** -->
<!-- ^5/13(五)Day26^
- 使用 [bcryptjs](https://www.npmjs.com/package/bcryptjs) 套件將密碼加密,==題目==成功新增的資料密碼不能為明碼
^5/16(一)Day27^
- [validator](https://www.npmjs.com/package/validator) 驗證使用者註冊資料(暱稱及密碼長度、email 格式)==題目==:新增 user 資料(POST `/sign_up`),、加入驗證
^5/17(二)Day28^
- JWT 介紹,==題目==:使用 JWT 產生 token
^5/18(三)Day29^
- ==題目==:將 JWT 加入註冊功能(POST `/sign_up`)中 -->
<!-- ^5/19(四)Day30^
- 使用 [bcryptjs](https://www.npmjs.com/package/bcryptjs) 套件將密碼解密比對是否符合(參考 [mongoose select()](https://mongoosejs.com/docs/api/query.html#:~:text=When%20using%20string%20syntax%2C%20prefixing%20a%20path%20with%20%2D%20will%20flag%20that%20path%20as%20excluded.%20When%20a%20path%20does%20not%20have%20the%20%2D%20prefix%2C%20it%20is%20included.%20Lastly%2C%20if%20a%20path%20is%20prefixed%20with%20%2B%2C%20it%20forces%20inclusion%20of%20the%20path%2C%20which%20is%20useful%20for%20paths%20excluded%20at%20the%20schema%20level.))、JWT 產生 token,==題目==:製作登入功能(POST `/sign_in`)
^5/20(五)Day31^
- 設計 isAuth 的 middleware 取得 request.header.authorization、驗證 token 是否正確([JWT 流程步驟 5](https://whimsical.com/jwt-UKUY1rj1vfoN6uyic7e4Sm)),==題目==:使用測試路由 GET `/test` 測試 isAuth middleware 是否有正確驗證 -->
<!-- :::spoiler isAuth middleware
```javascript
const isAuth = handleErrorAsync(async (req, res, next) => {
// 確認 token 是否存在
let token;
if (
req.headers.authorization &&
req.headers.authorization.startsWith('Bearer')
) {
token = req.headers.authorization.split(' ')[1];
}
if (!token) {
return next(appError(401,'你尚未登入!',next));
}
// 驗證 token 正確性
const decoded = await new Promise((resolve,reject)=>{
jwt.verify(token,process.env.JWT_SECRET,(err,payload)=>{
if(err){
reject(err)
}else{
resolve(payload)
}
})
})
console.log(decoded);
const currentUser = await User.findById(decoded.id);
req.user = currentUser;
next();
});
```
:::
^5/23(一)Day32^
- ==題目==:設計取得 user 資料路由 GET `/users/profile`,加入 isAuth middleware
^5/24(二)Day33^
- ==題目==:複習 [bcryptjs](https://www.npmjs.com/package/bcryptjs)、`generateSendJWT()`,設計重設密碼路由 PATCH
**第七週大綱**
- ==題目== multer 套件處理 request 傳過來的 `multipart/form-data`
資料,[multer(opts)](https://github.com/expressjs/multer#multeropts)、[fileFilter()](https://github.com/expressjs/multer#filefilter) 設定上傳圖檔驗證是否符合條件,完成上傳圖片 API
- 註冊 Imgur 應用程式(參考[文件](https://apidocs.imgur.com/#intro) 中的 **Register an Application (IMPORTANT)** 介紹)申請 `Client ID` 及 `Client secret`
- ==題目== [imgur 套件](https://www.npmjs.com/package/imgur/v/1.0.2)將圖片上傳至 imgur 空間
- [image-size 套件](https://github.com/image-size/image-size) 偵測圖片尺寸
-->
**第八週大綱**
- ==題目==:提供情境,回覆此情境的讀寫比例適合使用何種資料庫設計(embedded、一對一或一對多(關聯資料庫))
- ==題目==:提供情境,回覆此情境下,一個 document 是否會超過 16mb 的限制,依此判斷使用一對多 (1: few) 或一對多 (1: many) 的資料庫設計
<!-- - ==題目==:實作 POST DELETE 新增、取消一則貼文讚,posts Model 新增 likes 陣列 -->
- ==題目== POST DELETE [追蹤與取消追蹤功能](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/routes/users.js#L79-L133)
* [user model 增加欄位](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/models/users.js#L30-L47)
- ==題目==: POST:[新增一則貼文的留言](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/routes/posts.js#L133-L144)
* [增加 comment model](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/models/comment.js)
* [post model 增加虛擬欄位 comments](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/models/posts.js#L37-L54)
- ==題目== GET:[取得所有貼文,加上 comment](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/routes/posts.js#L22-L25)