---
tags: Node.js 直播班 - 2022 春季班
---
# 第二週 - Node.js NPM 整合 MongoDB
1. 錄影
2. 點名,[報到]() Code:`xHesHogOOTDd`
3. [Adobe XD 設計稿](https://xd.adobe.com/view/c0763dbe-fc15-42e8-be0b-8956ed03e675-9525/grid)
4. [講義簡報](https://whimsical.com/mongoose-YKTKL5aF4pHQbkemgQTMZH)
## 講解大綱
* Mongoose 講解
* Schema 設計
* 何謂 Model?
* 第二週主線任務設計
## 公布最終作業使用者故事
1. 此為 NFT 會員制的動態牆,僅有限量 VIP 可以加入討論
2. 在 NFT 合約上,有限制永久只有 500 位會員參與此平台
## NPM
* dotenv:環境變數
* [Mongoose](https://mongoosejs.com/)
## 常見 Mongoose 指令
### 連線語法
```=javascript
const http = require('http');
const mongoose = require('mongoose');
mongoose
.connect("mongodb://localhost:27017/testPost")
.then(() => console.log('資料庫連接成功'));
// schema 開始
// schema 結束
const requestListener = async(req, res)=>{
res.end();
}
const server = http.createServer(requestListener);
server.listen(3000);
```
> mongodb://localhost:27017/posts
### 建立 Schema
```=javascript
const postSchema = new mongoose.Schema(
{
content: {
type: String,
required: [true, 'Content 未填寫']
},
image: {
type:String,
default:""
},
createdAt: {
type: Date,
default: Date.now(),
select: false
},
name: {
type: String,
required: [true, '貼文姓名未填寫']
},
likes: {
type:Number,
default:0
}
}
);
const Post = mongoose.model('Post', postSchema);
const init = async()=>{
const AllPost = await Post.find();
console.log(AllPost)
}
init();
```
### CURD 語法
* 新增:[Model.create()](https://mongoosejs.com/docs/api/model.html#model_Model.create)
* 刪除:[Model.findByIdAndDelete()](https://mongoosejs.com/docs/api/model.html#model_Model.findByIdAndDelete)
* 更新:[Model.findByIdAndUpdate()](https://mongoosejs.com/docs/api/model.html#model_Model.findByIdAndUpdate)
* 查詢:[Model.find()](https://mongoosejs.com/docs/api/model.html#model_Model.find)
```
await Post.findByIdAndUpdate(id,editContent) // 更新單筆
await Post.deleteMany({}); //刪除全部
await Post.findByIdAndDelete(id); // 刪除單筆
```
:::spoiler 完整 Code
## code
```=JavaScript
const http = require('http');
const mongoose = require('mongoose');
mongoose
.connect("mongodb://localhost:27017/testPost")
.then(() => console.log('資料庫連接成功'));
const postSchema = new mongoose.Schema(
{
content: {
type: String,
required: [true, 'Content 未填寫']
},
image: {
type:String,
default:""
},
createdAt: {
type: Date,
default: Date.now(),
select: false
},
name: {
type: String,
required: [true, '貼文姓名未填寫']
},
likes: {
type:Number,
default:0
}
}
);
const Post = mongoose.model('post', postSchema);
const requestListener = async(req, res)=>{
const headers = {
'Access-Control-Allow-Headers': 'Content-Type, Authorization, Content-Length, X-Requested-With',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'PATCH, POST, GET,OPTIONS,DELETE',
'Content-Type': 'application/json'
}
let body = "";
req.on('data', chunk=>{
body+=chunk;
})
if(req.url=="/posts" && req.method == "GET"){
const post = await Post.find();
res.writeHead(200,headers);
res.write(JSON.stringify({
"status": "success",
post
}));
res.end();
}else if(req.url=="/posts" && req.method == "POST"){
req.on('end',async()=>{
try{
const data = JSON.parse(body);
if(data.content !== undefined){
const newPost = await Post.create(
{
name: data.name,
content: data.content,
}
);
res.writeHead(200,headers);
res.write(JSON.stringify({
"status": "success",
"data": newPost,
}));
res.end();
}else{
res.writeHead(400,headers);
res.write(JSON.stringify({
"status": "false",
"message": "欄位未填寫正確,或無此 todo ID",
}));
res.end();
}
}catch(error){
res.writeHead(400,headers);
res.write(JSON.stringify({
"status": "false",
"message": error,
}));
res.end();
}
})
}else if(req.url.startsWith("/posts/") && req.method=="DELETE"){
const id = req.url.split('/').pop();
await Post.findByIdAndDelete(id);
res.writeHead(200,headers);
res.write(JSON.stringify({
"status": "success",
"data": null,
}));
res.end();
}else if(req.method == "OPTIONS"){
res.writeHead(200,headers);
res.end();
}else{
res.writeHead(404,headers);
res.write(JSON.stringify({
"status": "false",
"message": "無此網站路由"
}));
res.end();
}
}
const server = http.createServer(requestListener);
server.listen(3000);
```
:::
## 商業思維學院 x 六角學院
* [2022 商務媒合咖啡廳 4/28(四) 下午](https://edm.bnext.com.tw/2022fc_match/)
* 第一線參與上市上櫃公司說明會
* **洧杰老師一對一線下 30 分鐘職涯規劃**
### 報名方式,僅限 7 位內推名額
* 私訊洧杰老師,並告知報名意願,之後再補履歷
* 審核通過後,會提供通關密語,可直接報名此[活動](https://edm.bnext.com.tw/2022fc_match/)
* 4/23(六) 23:59:59 截止報名
## 第二週主線任務
* [第二週主線任務網址]()
## 週末任務一(挑選一位)
請寫一篇部落格,幫助同學們,該如何將 mongoDB alsta 能只允許 heroku IP 造訪,而非全公開。([線索](https://www.mongodb.com/developer/how-to/use-atlas-on-heroku/#configuring-heroku-ip-addresses-in-mongodb-atlas))
## 週末任務二(挑選寫最好的前兩位送書)
請寫一篇部落格,解釋何謂 **callback function**,加分題是講解 express middleware 如何透過 callback function 實現
* [Genos - https://stark920.github.io/2022/04/17/JScallback/](https://stark920.github.io/2022/04/17/JScallback/)
* [邱繼緯(小麥)0.5本 - 了解 JavaScript 中的 callback function](https://ayugioh2003.github.io/2022/04/callback-function/)
* [Han Lai 0.5本 - 淺談 JavaScript Callback Function](https://hackmd.io/@laihan/S1nTlwY49)
* [Pon - 0.5本 - 回呼函式(callback function)](https://forest-lunge-74a.notion.site/callback-function-da5ef9fa618b437384e622e19b2d97ea)
## 週末任務三(挑選寫最好的前兩位送書)
請寫一篇部落格,講解你跟後端合作的時候,用哪個 Mock API 服務,造福大家
* [Albert(炸豆腐) - Mock API 身為前端該了解的知識點 ](https://callum.hashnode.dev/mock-api)
* [joe.chang - 別等了!用Mock Service Worker來產生Mock API吧!](https://medium.com/coding-hot-pot/%E5%88%A5%E7%AD%89%E4%BA%86-%E7%94%A8mock-service-worker%E4%BE%86%E7%94%A2%E7%94%9Fmock-api%E5%90%A7-f921ab30d5c7)
* [Leo Chuang - 使用Mocks Server快速建立Front-End mock API](https://medium.com/@dennis302218905/%E4%BD%BF%E7%94%A8mocks-server%E5%BF%AB%E9%80%9F%E5%BB%BA%E7%AB%8Bfront-end-mock-api-130a1876832b)