RxJS 提供了 pluck()
直接取得 Object 的 Property,若要取得部分 Property,RxJS 並沒有提供直接 Operator,此時可使用 RxJS 的 map()
+ Ramda 的 pick()
實現。
Version
macOS Catalina 10.15.5
WebStorm 2020.1.2
Vue 2.6.11
RxJS 6.5.5
Ramda 0.27.0
Browser
按下 Get Book
僅顯示 title
與 price
。
Data
{
"id": 1,
"title": "FP in JavaScript",
"price": 100,
"categoryId": 1,
"image": "fpjs.jpg"
}
http://localhost:3000/books/:id
會回傳指定 id
的書籍。
可發現 API 回傳了眾多不需要的 property,顯示只需要 title
與 price
。
map()
<template>
<div>
<button v-stream:click="{ subject: click$, data: 1 }">Get Book</button>
<ul>
<li v-for="(x, k) in book$" :key="k">{{ k }} : {{ x }}</li>
</ul>
</div>
</template>
<script>
import { ajax } from 'rxjs/ajax'
import { pluck, map, switchMap } from 'rxjs/operators'
let fetchBook$ = x => ajax(`http://localhost:3000/books/${x}`).pipe(
pluck('response')
)
let subscriptions = function() {
let book$ = this.click$.pipe(
pluck('data'),
switchMap(fetchBook$),
map(x => ({ "title": x.title, "price": x.price }))
)
return { book$ }
}
export default {
name:'App',
domStreams: [
'click$'
],
subscriptions
}
</script>
19 行
let book$ = this.click$.pipe(
pluck('data'),
switchMap(fetchBook$),
map(x => ({ "title": x.title, "price": x.price }))
)
可使用 map()
將所需 property 組合成 Object 回傳。
pick()
<template>
<div>
<button v-stream:click="{ subject: click$, data: 1 }">Get Book</button>
<ul>
<li v-for="(x, k) in book$" :key="k">{{ k }} : {{ x }}</li>
</ul>
</div>
</template>
<script>
import { ajax } from 'rxjs/ajax'
import { pluck, map, switchMap } from 'rxjs/operators'
import { pick } from 'ramda'
let fetchBook$ = x => ajax(`http://localhost:3000/books/${x}`).pipe(
pluck('response')
)
let subscriptions = function() {
let book$ = this.click$.pipe(
pluck('data'),
switchMap(fetchBook$),
map(pick(['title', 'price'])),
)
return { book$ }
}
export default {
name:'App',
domStreams: [
'click$'
],
subscriptions
}
</script>
20 行
let book$ = this.click$.pipe(
pluck('data'),
switchMap(fetchBook$),
map(pick(['title', 'price'])),
)
若要使 map()
的 callback 也 point-free,可使用 Ramda 的 pick()
,將所需的 property 以 Array 傳入。
pick()
[k] -> {k: v} -> {k: v}
從一個 Object 中抽取部分 property 成為新 Object
[k]
:要抽取的 property
{k: v}
:data 為 object
{k: v}
: 回傳新的 object
Conclusion
- Ramda 對於 Object 與 Array 的支援非常完整,RxJS 的 operator 大多只為了 Observable 本身設計,若要在 callback 中操作 Object 與 Array,別忘了 Ramda 這個神兵利器