投票ページの作成(Node.js)⑪修正など

前回はこちら。

html-css-javascript.hatenadiary.com

さて、候補者追加や投票の機能は完成しました。

なのですが、実際にやってみるとわかるのですが、投票をしてそれが反映されるまでに時間がかかります。

というわけでこの辺を修正していこうと思います。

反映までの時間がかかる原因と対策

これは明らかに以下が原因ですね。

.then((data) => {
  console.log(data.message);
  location.reload();
})

投票するごとにサーバーからデータを受け取ってページを全部読み込んで、再描画しています。

そりゃあ時間もかかります。

そんなことをせず、投票数だけ1増やせばいいんです。

そうすれば全部読み込んだり再描画する必要はなくなります。

というわけでlocation.reload()は削除一択です。

さらに同じことが候補追加のときも言えます。

候補を追加するだけなんですから、すべてを読み込んで描画するのではなく、候補追加のところだけ変更すればいいわけです。

ではどうするのかというと、GETで取得したところをすべて関数にしてしまいます。

それをリロードのところで呼び出すと、サーバーでの最新情報を描画することになります。

まずはGETを関数化。

function loadCandidates() {
  fetch("http://localhost:3000/api/candidates")
  .then((response) => {
    if (!response.ok) {
      throw new Error("HTTPエラー");
    }
    return response.json();
  })
  .then((data) => {
    console.log("取得したデータ:", data);
    candidates = data;
    candidateList.innerHTML = ""; // 念のためクリア
    render();
  })
  .catch((err) => {
    console.error(err);
    showError();
  }

showError();はエラーのときの処理です。

あとから定義します。

で、これを3か所で呼び出します。

location.reload();があったところです。

①定義したところ

まず一番最初にサーバーの最新状態を表示する必要があります。

なので定義した直後に呼び出す必要があります。

このとき、普通に呼び出してもいいのですが、タイミングを安定させるためにHTMLの読み込みを終了した後という風に書きます。

window.addEventListener("DOMContentLoaded", () => {
  loadCandidates();
});

DOMContenLoadedはclickとかsubmitと同じようなイベントで、HTMLの読み込みと解析が終わって、画面の部品(DOM)が全部使えるようになったタイミングで発生します。

で、そのタイミングでイベントが発火しますので、loadCandidates()が呼び出されます。

②クリックイベントのところ

.then((response) => response.json())
        .then((data) => {
          console.log(data.message);
          //location.reload();

③サブミットイベントのところ

 .then((response) => response.json())
      .then((data) => {
        console.log(data.message);

        inputName.value = "";
        inputAge.value = "";

        //location.reload(); ここ
        loadCandidates(); // 候補者リストを再読み込み

      })
      .catch((err) => {
        console.error(err);
      });
      .catch((err) => {
        console.error(err);
      });

この部分が被ってるように見えますが、loadCandidatesの中の方はGETに関するもので、その外の部分はPOSTに関するものなのでこの書き方で問題はありません。

これでページ全体をリロードするのではなく、renderの中身に定義されているようにDOM操作で要素のみを追加しているだけなので軽くなります。

実行・・・。

ちゃんと軽くなりました。

リロードボタン

そうすると、再読み込みをするボタンが欲しくなります。

このボタンも作っておきましょう。

HTMLに以下を追加します。

<button id="reloadBtn">再読み込み</button>

で、Script.jsに以下を追加します。

const reloadBtn = document.getElementById("reloadBtn");
if (reloadBtn) {
  reloadBtn.addEventListener("click", () => {
    loadCandidates();
  });
}

この辺はあっさりしたもんです。

VSCodeを使ってたら一瞬でできますね。

削除ボタン

管理人画面においては候補者の削除ボタンも必要になりますね。

JavaScriptのrenderでチェックボックスという新しい要素を追加するようにして、そこでチェックをできるようにして、削除ボタンを押したらfetchでバックエンドへチェックボックスの操作を処理するPOSTリクエストを送信、バックエンドで保存とフロントでの表示をするためにGETリクエストを受けてフロントで表示の処理、といった感じですね。

いっきに書いてしまいましたが、ちょっと長くなりそうなので次回に回します。

コメントを書く

投票ページの作成(Node.js)⑪修正など

プロフィール
注目記事