# ဘဏ်အက်ပ်တည်ဆောက်ခြင်း အပိုင်း ၃: ဒေတာရယူခြင်းနှင့် အသုံးပြုခြင်းနည်းလမ်းများ Star Trek မှ Enterprise ရဲ့ကွန်ပျူတာကိုစဉ်းစားကြည့်ပါ - Captain Picard သင်္ဘောအခြေအနေကိုမေးတဲ့အခါမှာ အချက်အလက်တွေဟာ interface တစ်ခုလုံးကိုပိတ်ပြီး ပြန်တည်ဆောက်စရာမလိုဘဲ ချက်ချင်းပေါ်လာပါတယ်။ ဒေတာကို dynamic data fetching နဲ့ seamless flow အနေနဲ့တည်ဆောက်တဲ့အခါမှာ ဒီလိုအတိအကျအတိုင်းဖြစ်လာမှာပါ။ အခုအချိန်မှာ သင့်ဘဏ်အက်ပ်ဟာ ပုံနှိပ်ထားတဲ့ သတင်းစာလိုပဲ - အချက်အလက်ပေးပေမယ့် static ဖြစ်နေပါတယ်။ NASA ရဲ့ mission control လိုပဲ ဒေတာတွေကို အဆက်မပြတ်စီးဆင်းပြီး အသုံးပြုသူရဲ့ workflow ကိုမထိခိုက်ဘဲ real-time update ဖြစ်အောင် ပြောင်းလဲပေးမှာဖြစ်ပါတယ်။ သင် asynchronous နည်းလမ်းနဲ့ server တွေနဲ့ဆက်သွယ်နည်း၊ အချိန်အမျိုးမျိုးမှာရောက်လာတဲ့ဒေတာတွေကို handle လုပ်နည်း၊ အသုံးပြုသူတွေအတွက် raw information ကို အဓိပ္ပါယ်ရှိတဲ့အရာတစ်ခုအဖြစ်ပြောင်းလဲနည်းတွေကိုလေ့လာရမှာဖြစ်ပါတယ်။ ဒီဟာက demo software နဲ့ production-ready software ကြားကအရေးကြီးတဲ့ကွာခြားချက်ပဲဖြစ်ပါတယ်။ ## မိန့်ခွန်းမတိုင်မီမေးခွန်း [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/45) ### ကြိုတင်လိုအပ်ချက်များ ဒေတာရယူခြင်းကိုစတင်မလုပ်ခင်မှာ အောက်ပါအချက်တွေကို ပြင်ဆင်ထားပါ: - **ယခင်သင်ခန်းစာ**: [Login and Registration Form](../2-forms/README.md) ကိုပြီးစီးထားပါ - ဒီအခြေခံပေါ်မှာဆောက်လုပ်သွားမှာဖြစ်ပါတယ်။ - **Local Server**: [Node.js](https://nodejs.org) ကို install လုပ်ပြီး [server API run](../api/README.md) လုပ်ပါ။ - **API Connection**: ဒီ command ကိုသုံးပြီး server connection ကိုစမ်းသပ်ပါ: ```bash curl http://localhost:5000/api # Expected response: "Bank API v1.0.0" ``` ဒီအမြန်စမ်းသပ်မှုက အစိတ်အပိုင်းအားလုံးအဆင်ပြေစွာဆက်သွယ်နေကြောင်းအတည်ပြုပေးပါမယ်: - သင့်စနစ်မှာ Node.js ကောင်းစွာ run နေကြောင်းအတည်ပြုပါမယ်။ - သင့် API server က active ဖြစ်ပြီး response ပေးနေကြောင်းအတည်ပြုပါမယ်။ - သင့်အက်ပ်က server ကိုရောက်ရှိနိုင်ကြောင်းအတည်ပြုပါမယ် (mission မစခင် radio contact စစ်ဆေးသလိုပဲ) --- ## ခေတ်မီ Web Apps တွေမှာ ဒေတာရယူနည်းကိုနားလည်ခြင်း Web applications တွေက ဒေတာကို handle လုပ်နည်းဟာ နောက်ဆုံးနှစ် ၂၀ အတွင်း အလွန်အမင်းတိုးတက်ပြောင်းလဲလာပါတယ်။ ဒီတိုးတက်မှုကိုနားလည်ခြင်းက ခေတ်မီနည်းလမ်းတွေဖြစ်တဲ့ AJAX နဲ့ Fetch API တွေက ဘာလို့အလွန်အစွမ်းထက်ပြီး web developers တွေအတွက်မရှိမဖြစ်အရေးကြီးတဲ့ tools တွေဖြစ်လာတယ်ဆိုတာကိုသိရှိစေမှာပါ။ ရိုးရာ website တွေက ဘယ်လိုအလုပ်လုပ်ခဲ့တယ်ဆိုတာနဲ့ ယနေ့ခေတ် dynamic, responsive applications တွေကိုတည်ဆောက်နည်းကိုလေ့လာကြည့်ရအောင်။ ### ရိုးရာ Multi-Page Applications (MPA) Web ရဲ့အစောပိုင်းကာလတွေမှာ click တစ်ချက်နဲ့ရုပ်မြင်သံကြား channel ပြောင်းတာလိုပဲ - screen ကအရင်ဆုံး blank ဖြစ်ပြီးနောက်မှ content အသစ်ကိုဖြည်းဖြည်း tune လုပ်ရပါတယ်။ ဒါကရိုးရာ web applications တွေမှာ page တစ်ခုလုံးကိုအပြည့်အဝပြန်တည်ဆောက်ရတဲ့အခါမှာဖြစ်ခဲ့တာပါ။ ```mermaid sequenceDiagram participant User participant Browser participant Server User->>Browser: Clicks link or submits form Browser->>Server: Requests new HTML page Note over Browser: Page goes blank Server->>Browser: Returns complete HTML page Browser->>User: Displays new page (flash/reload) ``` ![Update workflow in a multi-page application](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.my.png) **ဒီနည်းလမ်းက clunky ဖြစ်တဲ့အကြောင်းအရင်း:** - Click တစ်ချက်တိုင်းမှာ page တစ်ခုလုံးကိုပြန်တည်ဆောက်ရပါတယ်။ - အသုံးပြုသူတွေဟာ page flashes တွေကြောင့် mid-thought မှာ interruption ဖြစ်ရပါတယ်။ - Internet connection က header နဲ့ footer တူညီတဲ့အရာတွေကိုအကြိမ်ကြိမ် download လုပ်ရပါတယ်။ - Apps တွေဟာ software အသုံးပြုနေတဲ့အစား ဖိုင်တွေကိုရှာဖွေတဲ့ filing cabinet လိုခံစားရပါတယ်။ ### ခေတ်မီ Single-Page Applications (SPA) AJAX (Asynchronous JavaScript and XML) က ဒီ paradigm ကိုအပြည့်အဝပြောင်းလဲပေးခဲ့ပါတယ်။ International Space Station ရဲ့ modular design လိုပဲ astronauts တွေက structure တစ်ခုလုံးကိုပြန်တည်ဆောက်စရာမလိုဘဲ individual components တွေကိုအစားထိုးနိုင်ပါတယ်။ AJAX က webpage ရဲ့ specific parts တွေကို reload မလုပ်ဘဲ update လုပ်နိုင်စေပါတယ်။ XML ဆိုတဲ့နာမည်ပါပေမယ့် ယနေ့ခေတ်မှာ JSON ကိုအများဆုံးအသုံးပြုပါတယ်။ ဒါပေမယ့် core principle ကမပြောင်းလဲပါဘူး - လိုအပ်တဲ့အပိုင်းကိုသာ update လုပ်ပါ။ ```mermaid sequenceDiagram participant User participant Browser participant JavaScript participant Server User->>Browser: Interacts with page Browser->>JavaScript: Triggers event handler JavaScript->>Server: Fetches only needed data Server->>JavaScript: Returns JSON data JavaScript->>Browser: Updates specific page elements Browser->>User: Shows updated content (no reload) ``` ![Update workflow in a single-page application](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.my.png) **SPA တွေကပိုကောင်းတဲ့အကြောင်းအရင်း:** - တကယ်ပြောင်းလဲလိုက်တဲ့အပိုင်းတွေကိုသာ update လုပ်ပါတယ် (smart, right?) - Jarring interruptions မရှိတော့ပါဘူး - အသုံးပြုသူတွေ flow မှာဆက်ရှိနေပါတယ်။ - Wire ပေါ်မှာ data traveling လျော့နည်းတာကြောင့် loading ပိုမြန်ပါတယ်။ - Phone apps တွေလို snappy နဲ့ responsive ဖြစ်ပါတယ်။ ### ခေတ်မီ Fetch API သို့တိုးတက်မှု ခေတ်မီ browser တွေက [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API) ကိုပေးထားပြီး ရှေးဟောင်း [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest) ကိုအစားထိုးပါတယ်။ Telegraph ကို operate လုပ်တာနဲ့ email ကိုအသုံးပြုတာကြားကကွာခြားချက်လိုပဲ Fetch API က asynchronous code ကို promises နဲ့ပိုသန့်ရှင်းစေပြီး JSON ကိုသဘာဝအတိုင်း handle လုပ်ပါတယ်။ | Feature | XMLHttpRequest | Fetch API | |---------|----------------|----------| | **Syntax** | Complex callback-based | Clean promise-based | | **JSON Handling** | Manual parsing required | Built-in `.json()` method | | **Error Handling** | Limited error information | Comprehensive error details | | **Modern Support** | Legacy compatibility | ES6+ promises and async/await | > 💡 **Browser Compatibility**: သတင်းကောင်း - Fetch API ဟာ ခေတ်မီ browser တွေမှာအကုန်လုံးမှာအလုပ်လုပ်ပါတယ်! အတိအကျ version တွေကိုသိချင်ရင် [caniuse.com](https://caniuse.com/fetch) မှာ compatibility story အပြည့်အစုံရှိပါတယ်။ > **အကျဉ်းချုပ်:** - Chrome, Firefox, Safari, နဲ့ Edge (basically everywhere your users are) မှာအလုပ်လုပ်ပါတယ်။ - Internet Explorer ကသာအထောက်အပံ့လိုအပ်ပါတယ် (တကယ်တော့ IE ကိုစွန့်ပစ်ချိန်ရောက်ပြီ) - Elegant async/await patterns တွေကိုအသုံးပြုဖို့အတွက်အကောင်းဆုံးအခြေခံပေးပါတယ် ### အသုံးပြုသူ Login နဲ့ Data Retrieval ကိုတည်ဆောက်ခြင်း အခုတော့ သင့်ဘဏ်အက်ပ်ကို static display ကနေ functional application အဖြစ်ပြောင်းလဲစေမယ့် login system ကိုတည်ဆောက်ကြမယ်။ Secure military facilities တွေမှာအသုံးပြုတဲ့ authentication protocols လိုပဲ အသုံးပြုသူရဲ့ credentials ကို verify လုပ်ပြီး သူတို့ရဲ့ specific data ကို access ပေးပါမယ်။ ဒီကိုအဆင့်လိုက် incremental တည်ဆောက်သွားမှာဖြစ်ပြီး basic authentication ကနေစပြီး data-fetching capabilities တွေကိုထည့်သွင်းပါမယ်။ #### အဆင့် ၁: Login Function Foundation ကိုတည်ဆောက်ပါ `app.js` ဖိုင်ကိုဖွင့်ပြီး အသုံးပြုသူ authentication process ကို handle လုပ်မယ့် `login` function အသစ်တစ်ခုထည့်ပါ: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **ဒီကိုခွဲခြမ်းစိတ်ဖြာကြည့်ရအောင်:** - `async` keyword က JavaScript ကို "ဒီ function ဟာအချို့အရာတွေကိုစောင့်ရနိုင်တယ်" လို့ပြောပါတယ်။ - Form ကို page မှာ grab လုပ်ပါတယ် (အထူးအဆန်းမရှိပါဘူး၊ ID နဲ့ရှာဖွေပါတယ်) - အသုံးပြုသူရဲ့ username ကို form input မှာ type လုပ်ထားတာကိုယူပါတယ်။ - HTML မှာ `name` attribute ကိုသတ်မှတ်ထားတဲ့ form input တစ်ခုခုကို form element ရဲ့ property အနေနဲ့ access လုပ်နိုင်ပါတယ်။ > 💡 **Form Access Pattern**: Form control တစ်ခုချင်းစီကို HTML မှာ `name` attribute သတ်မှတ်ထားပြီး form element ရဲ့ property အနေနဲ့ access လုပ်နိုင်ပါတယ်။ Form data ကိုရယူဖို့အတွက် သန့်ရှင်းပြီးဖတ်ရှင်းလွယ်ကူတဲ့နည်းလမ်းပေးပါတယ်။ #### အဆင့် ၂: Account Data Fetching Function ကိုတည်ဆောက်ပါ နောက်တစ်ဆင့်မှာ server မှာ account data ကိုရယူဖို့အတွက် dedicated function တစ်ခုကိုတည်ဆောက်ပါ။ ဒါဟာ registration function pattern နဲ့တူပေမယ့် data retrieval ကိုအဓိကထားပါတယ်: ```javascript 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' }; } } ``` **ဒီ code ကအလုပ်လုပ်တာ:** - ခေတ်မီ `fetch` API ကိုအသုံးပြုပြီး asynchronous နည်းလမ်းနဲ့ data ကို request လုပ်ပါတယ်။ - GET request URL ကို username parameter နဲ့တည်ဆောက်ပါတယ်။ - URL မှာ special characters တွေကို handle လုပ်ဖို့ `encodeURIComponent()` ကိုအသုံးပြုပါတယ်။ - Response ကို JSON format ပြောင်းပြီး data manipulation လုပ်ဖို့အဆင်ပြေစေပါတယ်။ - Error တွေကို gracefully handle လုပ်ပြီး crash မဖြစ်စေဘဲ error object ကို return လုပ်ပါတယ်။ > ⚠️ **Security Note**: `encodeURIComponent()` function က URL မှာ special characters တွေကို handle လုပ်ပါတယ်။ Naval communications မှာ encoding systems တွေလိုပဲ message ကို intended အတိုင်းရောက်အောင်လုပ်ပေးပြီး "#" နဲ့ "&" လို characters တွေကိုမမှားအောင်ကာကွယ်ပေးပါတယ်။ > **အရေးကြီးချက်:** - Special characters တွေ URL ကိုမပျက်စီးစေပါဘူး။ - URL manipulation attacks ကိုကာကွယ်ပေးပါတယ်။ - Server ကို intended data ရောက်အောင်လုပ်ပေးပါတယ်။ - Secure coding practices ကိုလိုက်နာပါတယ်။ #### HTTP GET Requests ကိုနားလည်ခြင်း အံ့ဩစရာကောင်းတာတစ်ခုက `fetch` ကို extra options မပါဘဲအသုံးပြုတဲ့အခါမှာ default အနေနဲ့ [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) request ကို automatically create လုပ်ပါတယ်။ ဒါဟာ "ဒီအသုံးပြုသူရဲ့ account data ကိုကြည့်လို့ရမလား" လို့ server ကိုမေးတဲ့အတွက်အတိအကျအဆင်ပြေပါတယ်။ GET requests ကို library မှာစာအုပ် borrow လုပ်ဖို့တောင်းဆိုတာလိုပဲ - ရှိပြီးသားအရာကိုကြည့်ဖို့တောင်းဆိုတာပါ။ POST requests (registration မှာအသုံးပြုခဲ့တဲ့) ကအသစ်ထည့်သွင်းဖို့တောင်းဆိုတာလိုပါပဲ။ | GET Request | POST Request | |-------------|-------------| | **Purpose** | ရှိပြီးသား data ကိုရယူခြင်း | Server ကို data အသစ်ပို့ခြင်း | | **Parameters** | URL path/query string မှာ | Request body မှာ | | **Caching** | Browser တွေက cache လုပ်နိုင်ပါတယ် | Typically cache မလုပ်ပါဘူး | | **Security** | URL/logs မှာမြင်နိုင်ပါတယ် | Request body မှာလျှို့ဝှက်ထားပါတယ် | #### အဆင့် ၃: အားလုံးကိုပေါင်းစည်းခြင်း အခုတော့အကျိုးအမြတ်ရှိတဲ့အပိုင်း - account fetching function ကို login process နဲ့ချိတ်ဆက်ကြမယ်။ ဒီမှာအားလုံး click ဖြစ်သွားမှာပါ: ```javascript 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'); } ``` ဒီ function ကအဆင့်လိုက်အလုပ်လုပ်ပါတယ်: - Form input မှ username ကို extract လုပ်ပါတယ်။ - Server မှာအသုံးပြုသူရဲ့ account data ကို request လုပ်ပါတယ်။ - Process အတွင်းမှာဖြစ်ပေါ်တဲ့ error တွေကို handle လုပ်ပါတယ်။ - Account data ကိုသိမ်းပြီး success ဖြစ်တဲ့အခါ dashboard ကိုသွားပါတယ်။ > 🎯 **Async/Await Pattern**: `getAccount` ဟာ asynchronous function ဖြစ်တဲ့အတွက် server response ရလာတဲ့အထိ execution ကို `await` keyword နဲ့ pause လုပ်ပါတယ်။ ဒါက undefined data နဲ့ code ကိုဆက်မလုပ်စေဖို့ကာကွယ်ပေးပါတယ်။ #### အဆင့် ၄: သင့်ဒေတာအတွက်နေရာတစ်ခုဖန်တီးပါ သင့်အက်ပ်ဟာ load လုပ်ပြီးတဲ့အခါမှာ current user ရဲ့ data ကိုသိမ်းထားဖို့နေရာတစ်ခုလိုအပ်ပါတယ်။ ဒါကို app ရဲ့ short-term memory လိုပဲစဉ်းစားပါ - current user ရဲ့ data ကို handy ဖြစ်အောင်ထားတဲ့နေရာပါ။ `app.js` ဖိုင်ရဲ့ထိပ်မှာဒီလို line ကိုထည့်ပါ: ```javascript // This holds the current user's account data let account = null; ``` **ဒီဟာကိုဘာလို့လိုအပ်လဲ:** - Account data ကို app ရဲ့အခြားနေရာတွေကနေ access လုပ်နိုင်စေပါတယ်။ - `null` နဲ့စတင်တာက "အခုထိ login မလုပ်သေးဘူး" ဆိုတဲ့အဓိပ္ပါယ်ပါ။ - တစ်စုံတစ်ယောက် login လုပ်တာနဲ့ register လုပ်တာနဲ့ update လုပ်ပါတယ်။ - Single source of truth အနေနဲ့အလုပ်လုပ်ပါတယ် - login လုပ်ထားသူကိုရှုပ်ထွေးမှုမဖြစ်စေပါဘူး။ #### အဆင့် ၅: Form ကိုချိတ်ဆက်ပါ အခုတော့သင့်ရဲ့ login function အသစ်ကို HTML form နဲ့ချိတ်ဆက်ကြမယ်။ Form tag ကိုဒီလို update လုပ်ပါ: ```html
``` **ဒီအပြောင်းလဲမှုကဘာလုပ်ပေးလဲ:** - Form ရဲ့ default "reload the whole page" behavior ကိုရပ်တန့်စေပါတယ်။ - Custom JavaScript function ကိုခေါ်ပါတယ်။ - အားလုံးကို smooth နဲ့ single-page-app-like ဖြစ်စေပါတယ်။ - အသုံးပြုသူ "Login" ကိုနှိပ်တဲ့အခါမှာဘာဖြစ်မယ်ဆိုတာကိုအပြည့်အဝထိန်းချုပ်နိုင်ပါတယ်။ #### အဆင့် ၆: Registration Function ကိုတိုးတက်အောင်လုပ်ပါ Consistency ရရှိဖို့ `register` function ကို update လုပ်ပြီး account data ကိုသိမ်းပြီး dashboard ကိုသွားနိုင်အောင်လုပ်ပါ: ```javascript // Add these lines at the end of your register function account = result; navigate('/dashboard'); ``` **ဒီ enhancement ကပေးတဲ့အကျိုးကျေးဇူး:** - **Seamless** transition from registration to dashboard - **Consistent** user experience between login and registration flows - **Immediate** access to account data after successful registration #### သင့် Implementation ကိုစမ်းသပ်ပါ ```mermaid flowchart TD A[User enters credentials] --> B[Login function called] B --> C[Fetch account data from server] C --> D{Data received successfully?} D -->|Yes| E[Store account data globally] D -->|No| F[Display error message] E --> G[Navigate to dashboard] F --> H[User stays on login page] ``` **စမ်းသပ်ဖို့အချိန်ရောက်ပြီ:** 1. အားလုံးအဆင်ပြေမပြေစစ်ဖို့အတွက် account အသစ်တစ်ခုဖန်တီးပါ။ 2. အဲဒီ credentials တွေနဲ့ login လုပ်ကြည့်ပါ။ 3. Browser ရဲ့ console (F12) ကိုကြည့်ပါ၊ တစ်ခုခုမမှန်ရင် console မှာ error တွေရှိနိုင်ပါတယ်။ 4. Successful login ဖြစ်တဲ့အခါ dashboard မှာရောက်သွားတာကိုသေချာပါ။ တစ်ခုခုမအလုပ်လုပ်ရင် စိတ်မပူပါနဲ့! အများဆုံး issues တွေဟာ typos လိုအရာတွေဖြစ်နိုင်ပါတယ်၊ ဒါမှမဟုတ် API server run လုပ်ဖို့မမေ့ရပါဘူး။ #### Cross-Origin Magic အကြောင်းအနည်းငယ် သင့် web app က API server နဲ့အတူ different ports တွေမှာ run လုပ်နေတဲ့အခါ ဘယ်လိုဆက်သွယ်နေလဲဆိုတာကိုသင်မေးနိုင်ပါတယ်။ အလွန်ကောင်းတဲ့မေးခွန်းပါ! Web developer တစ်ယောက်အနေနဲ့အနောက်ဆုံး bump ဖြစ်မယ့်အရာတစ်ခုပါ။ > 🔒 **Cross-Origin Security**: Browser တွေက "same-origin policy" ကို enforce လုပ်ပြီး different domains တွေကြား unauthorized communication ကိုကာကွယ်ပေးပါတယ်။ Pentagon ရဲ့ checkpoint အကြမ်းမီးများသောအကြောင်းအရာများအတွက် [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) ကို [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) နည်းလမ်းနှင့်ပေါင်းစပ်အသုံးပြုပါ: ```javascript // Safe way to create new elements const transactionItem = document.createElement('div'); transactionItem.className = 'transaction-item'; transactionItem.textContent = `${transaction.date}: ${transaction.description}`; container.append(transactionItem); ``` **ဤနည်းလမ်းကိုနားလည်ခြင်း:** - **အသစ်**သော DOM element များကို programmatically ဖန်တီးသည် - **element attribute နှင့် အကြောင်းအရာများ**ကို အပြည့်အဝထိန်းချုပ်နိုင်သည် - **ရှုပ်ထွေးသော** element အဆင့်ဆင့်ဖွဲ့စည်းမှုများကို ခွင့်ပြုသည် - **အဆောက်အအုံနှင့် အကြောင်းအရာများ**ကို ခွဲခြားထားခြင်းဖြင့် လုံခြုံရေးကို ထိန်းသိမ်းထားသည် > ⚠️ **လုံခြုံရေးအတွေးအခေါ်**: [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) ကို tutorial များစွာတွင်တွေ့နိုင်သော်လည်း၊ embedded script များကို run လုပ်နိုင်သည်။ CERN တွင် unauthorized code execution ကိုတားဆီးထားသည့် လုံခြုံရေး protocol များကဲ့သို့၊ `textContent` နှင့် `createElement` ကို အသုံးပြုခြင်းသည် ပိုမိုလုံခြုံသော နည်းလမ်းများကို ပေးစွမ်းနိုင်သည်။ > **innerHTML ၏ အန္တရာယ်များ:** - User data ထဲရှိ `