# 銀行アプリを作成する Part 3: データの取得と利用方法 ## 講義前クイズ [講義前クイズ](https://ff-quizzes.netlify.app/web/quiz/45) ### はじめに すべてのウェブアプリケーションの中心には*データ*があります。データはさまざまな形を取りますが、その主な目的は常にユーザーに情報を表示することです。ウェブアプリがますますインタラクティブで複雑になるにつれ、ユーザーが情報にアクセスし、操作する方法はウェブ開発の重要な部分となっています。 このレッスンでは、サーバーから非同期でデータを取得し、そのデータを使用してHTMLを再読み込みせずにウェブページに情報を表示する方法を学びます。 ### 前提条件 このレッスンのためにウェブアプリの[ログインと登録フォーム](../2-forms/README.md)を作成している必要があります。また、[Node.js](https://nodejs.org)をインストールし、[サーバーAPI](../api/README.md)をローカルで実行してアカウントデータを取得する必要があります。 サーバーが正しく動作しているかどうかは、ターミナルで次のコマンドを実行して確認できます。 ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## AJAXとデータ取得 従来のウェブサイトでは、ユーザーがリンクを選択したりフォームを使用してデータを送信したりすると、HTMLページ全体を再読み込みすることで表示内容を更新します。新しいデータを読み込むたびに、ウェブサーバーは新しいHTMLページを返し、ブラウザがそれを処理する必要があります。このプロセスは現在のユーザー操作を中断し、再読み込み中のインタラクションを制限します。このワークフローは*マルチページアプリケーション (MPA)*とも呼ばれます。  ウェブアプリケーションがより複雑でインタラクティブになるにつれ、[AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming))という新しい技術が登場しました。この技術により、ウェブアプリはJavaScriptを使用してサーバーから非同期でデータを送受信し、HTMLページを再読み込みせずに更新を行うことが可能になり、より迅速な更新とスムーズなユーザーインタラクションを実現しました。サーバーから新しいデータを受信すると、現在のHTMLページをJavaScriptを使用して[DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) APIで更新することができます。このアプローチは進化を遂げ、現在では[*シングルページアプリケーション (SPA)*](https://en.wikipedia.org/wiki/Single-page_application)と呼ばれています。  AJAXが初めて導入された際、非同期でデータを取得するために利用可能な唯一のAPIは[`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest)でした。しかし、現在のブラウザでは、より便利で強力な[`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API)が実装されており、プロミスを使用し、JSONデータの操作に適しています。 > すべての最新ブラウザが`Fetch API`をサポートしていますが、ウェブアプリケーションを古いブラウザでも動作させたい場合は、[caniuse.comの互換性表](https://caniuse.com/fetch)を事前に確認することをお勧めします。 ### タスク [前回のレッスン](../2-forms/README.md)では、アカウントを作成するための登録フォームを実装しました。今回は既存のアカウントを使用してログインし、そのデータを取得するコードを追加します。`app.js`ファイルを開き、新しい`login`関数を追加してください。 ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; } ``` ここでは、`getElementById()`を使用してフォーム要素を取得し、次に`loginForm.user.value`を使用して入力からユーザー名を取得します。すべてのフォームコントロールは、HTMLで`name`属性を使用して設定された名前をプロパティとしてフォームからアクセスできます。 登録時に行った操作と同様に、サーバーリクエストを実行するための別の関数を作成しますが、今回はアカウントデータを取得するためのものです。 ```js async function getAccount(user) { try { const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user)); return await response.json(); } catch (error) { return { error: error.message || 'Unknown error' }; } } ``` `fetch` APIを使用してサーバーから非同期でデータをリクエストしますが、今回はデータをクエリするだけなので、URL以外の追加パラメータは必要ありません。デフォルトでは、`fetch`は[`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTPリクエストを作成しますが、これが今回求めているものです。 ✅ `encodeURIComponent()`はURL内の特殊文字をエスケープする関数です。この関数を呼び出さずに直接`user`値をURLに使用すると、どのような問題が発生する可能性があるでしょうか? 次に、`login`関数を更新して`getAccount`を使用します。 ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; const data = await getAccount(user); if (data.error) { return console.log('loginError', data.error); } account = data; navigate('/dashboard'); } ``` まず、`getAccount`が非同期関数であるため、サーバーの結果を待つために`await`キーワードを使用する必要があります。サーバーリクエストでは常にエラーケースに対処する必要がありますが、現時点ではエラーメッセージをログに表示するだけにしておき、後で戻ってきます。 次に、後でダッシュボード情報を表示するためにデータを保存する必要があります。`account`変数がまだ存在しないため、ファイルの先頭にグローバル変数を作成します。 ```js let account = null; ``` ユーザーデータが変数に保存された後、既存の`navigate()`関数を使用して*ログイン*ページから*ダッシュボード*に移動できます。 最後に、ログインフォームが送信されたときに`login`関数を呼び出す必要があります。HTMLを次のように変更してください。 ```html