JavaScript - Destructuring 解構


Posted by urlun0404 on 2022-03-29

這幾天在複習後端和製作RESTful API,想用解構的方式把 req.body 拆成變數,再用mongoose傳入mongoDB更新資料。

例如我預期可以接收到API參數有 id, name, age, major, merit, other,所以寫了一個解構語法拆解 req.body 物件 const {id, name, age, major, merit, other} = req.body;

假設使用者只在 name 和 age 輸入參數值,結果發現在沒有給定屬性預設值的情況下,即使解構時特別指定變數名稱,沒對應到物件屬性就不會被解構出來。

換句話說JS的解構語法,只會解構出有屬性存在的變數,因此上述解構出來的變數只存在 nameage

會造成什麼樣的問題?

我在連結資料庫更新資料的方式是,傳入 id 去查找。

如果使用者沒輸入 id,在用 mongoose 的 findOneAndUpdate() 因為不會輸入查詢值,就會直接跳出查詢,而且我也不會收到錯誤😅

為了避免沒有輸入 id ,我這邊是給定 id=null (下圖),因為 mongoose 的 Schema 有設定 id:{required: true},在更新資料那邊會偵測 id 是否為 null,若沒有就會給錯誤訊息,所以我就可以用 res.send(error) 偷懶地把 mongoose 錯誤訊息傳回去給使用API的人。


目前的解決辦法?

目前想到兩種解決辦法。

第一個是:先把每個解構的變數都給定預設值,強迫每個變數在解構沒有取得變數值的情況下,確保有這個變數且值為 null,例如:

const {
    id = null
    , name = null
    , age = null
    , major = null
    , merit = null
    , other = null
} = req.body;

並且在查找前就要判斷 id === null ,不過這邊就是不想加入自訂錯誤訊息的偷懶作法,之後有修正更正確的版本再回來更新圖片。

(2022.05.26 Updated)
第二種作法是先確認 req.body 是否擁有所有需要更新的屬性資料,我這邊的作法是用 Array 的 every method 去確認 req.body 是否有同名的key。確認無誤才把 req.body 拿去更新資料庫。

const properties = ["id", "name", "age", "major", "merit", "other"];
if(properties.every(p => p in req.body){
    res.status(400)
        .send({
            "Error": "Please update all the property value of this data"
        })
} else{
    // destructuring req.body and put the data into database
}

後記:
速看了一下MDN好像也沒特別說這件事, 還是這是常識? 總之先記錄一下這個發現。


References


#frontend #javascript #note







Related Posts

Top issues on OWASP

Top issues on OWASP

質數判斷演算法

質數判斷演算法

一起來讀論文 - Robot Learning via Human Adversarial Games

一起來讀論文 - Robot Learning via Human Adversarial Games


Comments