# ব্যাংকিং অ্যাপ তৈরি করুন পার্ট ৩: ডেটা সংগ্রহ এবং ব্যবহার করার পদ্ধতি ## প্রাক-লেকচার কুইজ [প্রাক-লেকচার কুইজ](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)) উদ্ভূত হয়। এই কৌশলটি ওয়েব অ্যাপগুলিকে জাভাস্ক্রিপ্ট ব্যবহার করে সার্ভার থেকে অ্যাসিঙ্ক্রোনাসভাবে ডেটা পাঠাতে এবং সংগ্রহ করতে দেয়, HTML পেজ পুনরায় লোড না করেই, যা দ্রুত আপডেট এবং মসৃণ ব্যবহারকারীর ইন্টারঅ্যাকশন প্রদান করে। যখন সার্ভার থেকে নতুন ডেটা পাওয়া যায়, তখন বর্তমান HTML পেজটি জাভাস্ক্রিপ্ট ব্যবহার করে [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