# ব্যাংকিং অ্যাপ তৈরি করুন পার্ট ৩: ডেটা আনার এবং ব্যবহারের পদ্ধতি ## প্রাক-লেকচার কুইজ [প্রাক-লেকচার কুইজ](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