點燈坊

失くすものさえない今が強くなるチャンスよ

使用 Promise 處理 POST

Sam Xiao's Avatar 2021-05-20

實務上常遇到 API 需要以 POST 以 Body 傳入,由於 Composition API 沒有使用 this,在 Vue 3 將有不同處理方式。

Version

Vue 3.0.11

Composition API

post000

按下 Submit 後會將 IDPassword 以 POST 傳入資料。

api/login.js

import axios from 'axios'

export default body => axios.post('/login', body)

使用 axios.post() 傳入 body

App.vue

<template lang='pug'>
div
  span ID
  input(v-model='id')
div
  span Password
  input(v-model='password', type='password')
div
  button(@click='onClick') Submit
div {{ result.id }}
div {{ result.password }}
</template>

<script setup>
import login from '/src/api/login'

ref: id = ''
ref: password = ''
ref: result = {}

let onClick = () => {
  login({ id, password })
    .then(x => x.data)
    .then(x => result = x)
    .catch(console.error)
}
</script>

21 行

let onClick = () => {
  login({ id, password })
    .then(x => x.data)
    .then(x => result = x)
    .catch(console.error)
}
  • 使用 { id, password } 以 Object 傳入 login()
  • 由於 login() 回傳 Promise,接下來處理都在 then()

Point-free

post000

結果不變,但使用 Point-free 改寫。

<template lang='pug'>
div
  span ID
  input(v-model='id')
div
  span Password
  input(v-model='password', type='password')
div
  button(@click='onClick') Submit
div {{ result.id }}
div {{ result.password }}
</template>

<script setup>
import { ref, unref } from 'vue'
import { write } from 'vue3-fp'
import { pipe, andThen as then, otherwise, prop, zipObj } from 'ramda'
import { error } from 'wink-fp'
import login from '/src/api/login'

let id = ref('')
let password = ref('')
let result = ref({})

let onClick = pipe(
  () => [unref(id), unref(password)],
  zipObj(['id', 'password']),
  login,
  then(prop('data')),
  then(write(result)),
  otherwise(error)
)
</script>

25 行

let onClick = pipe(
  () => [unref(id), unref(password)],
  zipObj(['id', 'password']),
  login,
  then(prop('data')),
  then(write(result)),
  otherwise(error)
)

使用 pipe() 組合 onClick()

  • () => [unref(id), unref(password)]:使用 unref() 讀取 state 並以 Array 回傳
  • zipObj(['id', 'password']):組合出 Object 準備傳入 login()
  • login:呼叫 API function 並回傳 Promise
  • then(prop('data')):在 Promise 內將 data prop 取出
  • then(write(result)):在 Promise 內寫入 result state
  • otherwise(error):處理 Rejected Promise

Conclusion

  • Vue 3 Composition API 由於沒有使用 this,使得 Point-free 成為可能,event handler 都可以直接以 pure function 組合出來