カテゴリー
サインイン 新規登録

間違いや改善の指摘

内容の技術的な誤り・誤字脱字やミスのご報告・解説やトピックの追記/改善のご要望は教材をさらに良くしていく上でとても貴重なご意見になります。

少しでも気になった点があれば、ご遠慮なく投稿いただけると幸いです🙏

実際には誤りではなく勘違いであっても、ご報告いただけることで教材のブラッシュアップにつながります。

質問ポリシー①

教材受講者みなさんのスムーズな問題解決のために、心がけていただきたいことがあります。

教材の内容に関する質問を投稿しましょう

教材の内容に関係のない質問や教材とは異なる環境・バージョンで進めている場合のエラーなど、教材に関係しない質問は推奨していないため回答できない場合がございます。

その場合、teratailなどの外部サイトを利用して質問することをおすすめします。教材の誤字脱字や追記・改善の要望は「文章の間違いや改善点の指摘」からお願いします。

2-12

「前のページへ」「次のページへ」リンクを正式に実装する(実装編)

カリキュラム2-9から、

  1. 移動先のページ指定を固定した仮の「次のページへ」リンクを作成し、そのリンクをクリックしたら、指定したページに該当する記事一覧を表示できるようにする
  2. 「前のページへ」「次のページへ」リンクに組み込む移動先のページ指定を、現在のページ番号から算出してセットできるようにする

という2段階の対応の内、1の対応を進めてきました。

前パートで1の対応は完了したので、カリキュラム2-122-15にかけては、2番目の「前のページへ」「次のページへ」リンクを正式な形で実装する対応を行っていきます。

本パートの目標

  • views/blog.ejsのテンプレート出力処理内から現在のページ番号を参照できるようにする
  • 「前のページへ」「次のページへ」リンクに組み込む移動先のページ指定を、現在のページ番号から算出してセットできるようにする

本パート終了時には以下のような状態になります。

「前のページへ」リンクの確認

本パートを進める前の準備

  • VSCodeのコンソールからnpm startでサーバーアプリケーションを起動させてください。

現在のページ番号をテンプレート出力処理に渡すように変更する

まず、「前のページへ」「次のページへ」リンク作成に必要な情報である「現在のページ番号」をviews/blog.ejsのテンプレート出力処理に渡すように/blog/ルーティング処理を変更します。

VSCodeのファイル一覧からserver.jsを選択して、エディタで表示させてください。

そして、/blog/ルーティング処理のコードを以下のように変更してください。

server.js
12345678910111213141516
-++
Copied!
app.get('/blog/', (request, response) => { // ========== 中略 ========== // ページに応じた記事一覧に絞る(1ページ5件) const startIndex = (request.query.page - 1) * 5; const endIndex = startIndex + 5; const displayEntries = entries.slice(startIndex, endIndex); // テンプレートを使用して出力したHTMLをクライアントに送信 response.render('blog', { entries: displayEntries, sideList sideList, currentPage: request.query.page }); });

上記変更部分のsideListの行は単純に末尾にカンマを追加しただけなので、処理の動きを変更するものではありません。

実質的な変更部分は、views/blog.ejsのテンプレート出力処理にcurrentPageというプロパティを渡す部分になります。

currentPageの内容はrequest.query.pageとなっています。これは前パートで確認した、URLパラメータである?page=xxです。

この変更により、views/blog.ejsのテンプレート出力処理内からcurrentPageという変数名で現在のページ番号を参照できるようになりました。

テンプレート出力処理内で現在のページ番号を参照して「前のページへ」「次のページへ」リンクに組み込む

次に、views/blog.ejsのテンプレート出力処理の変更を行います。

VSCodeのファイル一覧からviews/blog.ejsを選択して、エディタで表示させてください。

そして、<div class="page-links">タグ内(前パートで仮の「次のページへ」リンクを追加した部分)のコードを以下のように変更してください。

views/blog.ejs
123456789101112
-++
Copied!
<div class="main-content"> <h1><a href="/blog/">担当者Aのブログ</a></h1> <article> <!---------- 中略 ----------> </article> <div class="page-links"> <a href="?page=3">次のページへ</a> <a href="?page=<%= currentPage - 1 %>">前のページへ</a> <a href="?page=<%= currentPage + 1 %>">次のページへ</a> </div> </div>

前パートで設置した仮の「次のページへ」リンクを消し、正式な「前のページへ」「次のページへ」リンクを設置しています。

「前のページへ」リンクの内容について解説します。

diff
1
+
Copied!
<a href="?page=<%= currentPage - 1 %>">前のページへ</a>

hrefのリンク先指定の中で<%= ~ %>というタグが使用されています。

カリキュラム2-3で触れましたが、<%の後に=が付いている場合は、タグ内の変数もしくは処理結果をそのまま文字列として出力するという指定になります。

この<%= ~ %>の中で、先ほど/blog/ルーティング処理で新たに追加したcurrentPageを参照しています。

?page=3というURLパラメータが指定されている場合は、このcurrentPage3が入ってくることになります。

この行は「前のページへ」リンクなので、現在のページ番号の1つ前であるcurrentPage - 1という指定になっています。

したがって、現在のページ番号が3の場合、HTMLとして出力される上記リンクのhref?page=2となります。

「次のページへ」リンクもほぼ同様の内容です。

diff
1
+
Copied!
<a href="?page=<%= currentPage + 1 %>">次のページへ</a>

「前のページへ」リンクがcurrentPage - 1だったのに対し、「次のページへ」リンクではcurrentPage + 1という指定になっています。

つまり、現在のページ番号が3の場合、HTMLとして出力される上記リンクのhref?page=4となります。

これでテンプレート側の修正も完了したので、ブラウザで出力内容を確認してみましょう。

ブラウザで「前のページへ」「次のページへ」リンクのURLを確認する

ブラウザのアドレスバーにhttp://127.0.0.1:15864/blog/?page=3と入力してエンターを押してください。

記事一覧ページが表示されます。

また、一番下までスクロールすると「前のページへ」「次のページへ」リンクが追加されているのが確認できます。

追加したリンクの確認

それぞれのリンク先URLを確認してみましょう。

まず、「前のページへ」リンクです。「前のページへ」リンクにマウスカーソルを合わせるとブラウザの左下にリンク先のURLが表示されます。

「前のページへ」リンクの確認

想定通りhttp://127.0.0.1:15864/blog/?page=2というURLになっています。

次に「次のページへ」リンクを見てみましょう。同じように「次のページへ」リンクにマウスカーソルを合わせてください。

「次のページへ」リンクの確認(誤)

???こちらは想定外の内容となっています。

想定ではhttp://127.0.0.1:15864/blog/?page=4となるはずが、http://127.0.0.1:15864/blog/?page=31となっています。

31という数字はどこから出てきたのでしょう。

実は、これは31(さんじゅういち)という数値ではなく、'31'(さんいち)という文字列になってしまっているのです。

カリキュラム2-10で確認したrequest.queryの内容を思い出してみましょう。

request.queryの内容

request.queryの内容は{ page: '3' }となっていました。

3がシングルクォーテーションで囲まれているということは、この3は文字列であるということです。

URLに付加されたパラメータはすべて文字列としてrequery.queryに登録されます。

/blog/ルーティング処理では、このrequest.queryに登録されたpageプロパティをそのままcurrentPageとしてviews/blog.ejsのテンプレート出力処理に渡しています。

つまり、views/blog.ejsのテンプレート出力処理内のcurrentPage3という数値ではなく、'3'という文字列であるということです。

先ほど追加した「次のページへ」リンクの設定は以下のようになっています。

html
1
Copied!
<a href="?page=<%= currentPage + 1 %>">次のページへ</a>

したがって、currentPage + 1というのは、'3' + 1という計算と同義ということです。

JavaScriptにおいての+演算子には、数値の加算の他に文字列の連結という働きがあります。

そして、+の左辺右辺どちらかが文字列の場合は、文字列の連結として動作します(1'1'という文字列として扱われる)。

currentPage'3'は数字ではあっても型としては数値ではなく文字列なので、'3' + '1' = '31'という結果になってしまったのです。

では、なぜ「前のページへ」リンクは大丈夫だったのでしょうか。

+と違い、-には文字列を操作する挙動は存在しないので、-が指定された時点で数値の減算として実行されます。

そのおかげで、'3' - 13 - 1 = 2として動作したということです。

ただ、これはそういう仕様に恵まれてたまたま正常に動作しただけの話なので、加算・減算をする値ということであれば、根本的にはcurrentPageの型は数値であるべきです。

次のパートでは、currentPageの型を数値に変更し、「次のページへ」リンクのURLが想定通りの内容になるように修正していきます。

本パートは以上になります。

お疲れ様でした。