過去の記事を整理した。
消すまでではないけれど、公開することもないかな。。。という記事を非公開にした。
カテゴリーやタグにあった項目も今となっては使わなくなっていたり、あることで余計に記事の属性が分かりにくくなりそうな部分を直した。
NotionDB上の記事はすっかりキレイになったんだけど、ブログ画面を確認してみると調整が必要な箇所に遭遇した。
そこで2点直すことにした。
直している最中にキャッシュのif文が重複している箇所を発見したのでそこも修正した。
※ 今回のタグやカテゴリー関連以外のキャッシュ処理も重複していたので後日直すことにする
getAllTags()はキャッシュがあればgetAllPosts()を使って処理するようになっていた。
export async function getAllTags(): Promise<string[]> {
if (blogIndexCache.exists()) {
const allPosts = await getAllPosts()
return [...new Set(allPosts.flatMap((post) => post.Tags))].sort()
}
const res = (await client.databases.retrieve({
database_id: DATABASE_ID,
})) as unknown as responses.RetrieveDatabaseResponse
return res.properties.Tags.multi_select.options
.map((option) => option.name)
.sort()
}キャッシュがあればgetAllPostsを使い、キャッシュがなければNotionAPIにリクエストを飛ばす。
でも、getAllPostsもキャッシュのあるなしで同じ分岐をさせていた。
export async function getAllPosts(): Promise<Post[]> {
let results = []
if (blogIndexCache.exists()) {
results = blogIndexCache.get()
console.log('Found cached posts.')
} else {
const params: QueryDatabaseParameters = {
database_id: DATABASE_ID,
filter: _buildFilter(),
sorts: [
{
property: 'Date',
direction: 'descending',
},
],
page_size: 100,
}
while (true) {
const res = await client.databases.query(params)
results = results.concat(res.results)
if (!res.has_more) {
break
}
params['start_cursor'] = res.next_cursor
}
}
return results
.filter((pageObject) => _validPageObject(pageObject))
.map((pageObject) => _buildPost(pageObject))
}getAllPostsを使えばキャッシュの有無の分岐がなされる。
ならば、getAllTagsはキャッシュの有無の分岐からはじめる必要はないのでは!?
という意図で以下のように直すことにした。
export async function getAllTags(): Promise<string[]> {
const allPosts = await getAllPosts()
return [...new Set(allPosts.flatMap((post) => post.Tags))].sort()
}getCategorysも同じ処理なので同様に直した。
修正前のgetAllTagsで使われていたclient.databases.retrieveというNotionAPIの関数が行っていた処理は、NotionDBに登録されているTagsプロパティの内容だった。
これに対し、
修正後の方は、getAllTags上ではキャッシュ判定はせず、getAllPosts内でキャッシュ判定をした後に動くclient.databases.queryは記事で使用されているTags情報を取って来ている。
だから、修正前では記事で使用していないがNotionDBには存在しているTagsがリストに表示されるという現象があった。
今回、たまたま不具合を発見した。
実際に必要になって使用したらプログラムが対応していなかったことが分かった。
あらゆるシーンを想定してプログラムすることが理想だけど、作っている時には考えが及ばないことはある。
これは仕方ない。
使えば使うだけブログのプログラムが成長する。
だから使っていきたいと改めて感じた。
直していた時に、関連の関数の記述が気になって勉強した。以下参照
開発環境かどうかで分岐している関数。
このconditionsって具体的にどんな内容なのかがイメージできていなかったことに気づいた。
function _buildFilter(conditions = []) {
if (process.env.NODE_ENV === 'development') {
return { and: conditions }
}
return {
and: _uniqueConditions(
conditions.concat([
{
property: 'Published',
checkbox: {
equals: true,
},
},
{
property: 'Date',
date: {
on_or_before: new Date().toISOString(),
},
},
])
),
}
}
実際に_buildFilters([ ])に渡しているところを観察してみる。
const params: QueryDatabaseParameters = {
database_id: DATABASE_ID,
filter: _buildFilter([
{
property: 'Rank',
number: {
is_not_empty: true,
},
},
]),
sorts: [
{
property: 'Rank',
direction: 'descending',
},
],
page_size: pageSize,
}
propertyの情報が入れられていることが分かる。
_buildFilterではpropertyとして渡ってくる情報をAND条件にして返すということだ。
また、開発環境ではない場合には渡ってきたproperty情報にpropertyのpublishedとdateを加えて返している。
propertyをconcatする時に動かす_uniqueConditionsでは何をしているのか?
function _uniqueConditions(conditions = []) {
const properties = []
return conditions.filter((cond) => {
if (properties.includes(cond.property)) {
return false
}
properties.push(cond.property)
return true
})
}渡ってきたpropertyのあとにconcatで指定しているpropertyのpublishedとdateがある。
このとき、渡ってきたpropertyと指定していたpropertyとが重複する場合がある。
例えばこんな感じ↓
propertyの重複がないように処理している関数だった。
私はこの、先に登場する const properties = [] という変数がどうも苦手だ。
propertyの処理について少しばかり理解が深まった気がする。☻