27 KiB
بینکنگ ایپ بنائیں حصہ 3: ڈیٹا حاصل کرنے اور استعمال کرنے کے طریقے
لیکچر سے پہلے کا کوئز
تعارف
ہر ویب ایپلیکیشن کے مرکز میں ڈیٹا ہوتا ہے۔ ڈیٹا مختلف شکلیں اختیار کر سکتا ہے، لیکن اس کا بنیادی مقصد ہمیشہ صارف کو معلومات فراہم کرنا ہوتا ہے۔ جیسے جیسے ویب ایپس زیادہ انٹرایکٹو اور پیچیدہ ہوتی جا رہی ہیں، صارف کے معلومات تک رسائی اور ان کے ساتھ تعامل ویب ڈیولپمنٹ کا ایک اہم حصہ بن چکا ہے۔
اس سبق میں، ہم دیکھیں گے کہ سرور سے ڈیٹا کو غیر متزامن طور پر کیسے حاصل کیا جائے، اور اس ڈیٹا کو HTML کو دوبارہ لوڈ کیے بغیر ویب صفحے پر معلومات دکھانے کے لیے کیسے استعمال کیا جائے۔
پیشگی شرط
آپ کو اس سبق کے لیے ویب ایپ کا لاگ ان اور رجسٹریشن فارم حصہ بنانا ہوگا۔ آپ کو Node.js انسٹال کرنا ہوگا اور سرور API کو چلانا ہوگا تاکہ آپ کو اکاؤنٹ کا ڈیٹا مل سکے۔
آپ یہ کمانڈ ٹرمینل میں چلا کر چیک کر سکتے ہیں کہ سرور صحیح طریقے سے چل رہا ہے:
curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result
AJAX اور ڈیٹا حاصل کرنا
روایتی ویب سائٹس میں جب صارف لنک منتخب کرتا ہے یا فارم کے ذریعے ڈیٹا جمع کراتا ہے تو دکھائی جانے والی مواد کو اپ ڈیٹ کرنے کے لیے پورے HTML صفحے کو دوبارہ لوڈ کیا جاتا ہے۔ جب بھی نیا ڈیٹا لوڈ کرنے کی ضرورت ہوتی ہے، ویب سرور ایک بالکل نیا HTML صفحہ واپس کرتا ہے جسے براؤزر کے ذریعے پروسیس کرنا پڑتا ہے، جو موجودہ صارف کی کارروائی میں خلل ڈالتا ہے اور دوبارہ لوڈ کے دوران تعامل کو محدود کرتا ہے۔ اس ورک فلو کو ملٹی پیج ایپلیکیشن یا MPA بھی کہا جاتا ہے۔
جب ویب ایپلیکیشنز زیادہ پیچیدہ اور انٹرایکٹو ہونا شروع ہوئیں، تو ایک نئی تکنیک AJAX (Asynchronous JavaScript and XML) سامنے آئی۔ یہ تکنیک ویب ایپس کو جاوا اسکرپٹ کا استعمال کرتے ہوئے سرور سے غیر متزامن طور پر ڈیٹا بھیجنے اور حاصل کرنے کی اجازت دیتی ہے، بغیر HTML صفحے کو دوبارہ لوڈ کیے، جس کے نتیجے میں تیز اپ ڈیٹس اور ہموار صارف تعاملات ہوتے ہیں۔ جب سرور سے نیا ڈیٹا موصول ہوتا ہے، تو موجودہ HTML صفحہ کو جاوا اسکرپٹ کے ذریعے DOM API کا استعمال کرتے ہوئے بھی اپ ڈیٹ کیا جا سکتا ہے۔ وقت کے ساتھ، یہ طریقہ کار اب سنگل پیج ایپلیکیشن یا SPA کے نام سے جانا جاتا ہے۔
جب AJAX پہلی بار متعارف کرایا گیا تھا، تو غیر متزامن طور پر ڈیٹا حاصل کرنے کے لیے دستیاب واحد API XMLHttpRequest تھا۔ لیکن جدید براؤزرز اب زیادہ آسان اور طاقتور Fetch API کو بھی نافذ کرتے ہیں، جو وعدوں کا استعمال کرتا ہے اور JSON ڈیٹا کو جوڑنے کے لیے زیادہ موزوں ہے۔
جب کہ تمام جدید براؤزرز
Fetch APIکو سپورٹ کرتے ہیں، اگر آپ چاہتے ہیں کہ آپ کی ویب ایپلیکیشن پرانے براؤزرز پر کام کرے تو ہمیشہ caniuse.com پر مطابقت کی جدول کو پہلے چیک کرنا اچھا خیال ہے۔
کام
پچھلے سبق میں ہم نے اکاؤنٹ بنانے کے لیے رجسٹریشن فارم نافذ کیا تھا۔ اب ہم موجودہ اکاؤنٹ کا استعمال کرتے ہوئے لاگ ان کرنے اور اس کا ڈیٹا حاصل کرنے کے لیے کوڈ شامل کریں گے۔ app.js فائل کھولیں اور ایک نیا login فنکشن شامل کریں:
async function login() {
const loginForm = document.getElementById('loginForm')
const user = loginForm.user.value;
}
یہاں ہم getElementById() کے ساتھ فارم عنصر حاصل کرنے سے شروع کرتے ہیں، اور پھر ہم loginForm.user.value کے ساتھ ان پٹ سے صارف نام حاصل کرتے ہیں۔ ہر فارم کنٹرول کو اس کے نام (HTML میں name ایٹریبیوٹ کے ذریعے سیٹ کیا گیا) کے طور پر فارم کی پراپرٹی کے طور پر حاصل کیا جا سکتا ہے۔
رجسٹریشن کے لیے جو ہم نے کیا تھا اسی طرح، ہم سرور کی درخواست انجام دینے کے لیے ایک اور فنکشن بنائیں گے، لیکن اس بار اکاؤنٹ کا ڈیٹا حاصل کرنے کے لیے:
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 HTTP درخواست بناتا ہے، جو ہم یہاں تلاش کر رہے ہیں۔
✅ encodeURIComponent() ایک فنکشن ہے جو URL کے لیے خاص کرداروں کو فرار کرتا ہے۔ اگر ہم اس فنکشن کو کال نہ کریں اور URL میں براہ راست user ویلیو استعمال کریں تو ہمیں ممکنہ طور پر کیا مسائل ہو سکتے ہیں؟
اب ہم اپنے login فنکشن کو getAccount استعمال کرنے کے لیے اپ ڈیٹ کرتے ہیں:
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 ویریبل ابھی موجود نہیں ہے، ہم اپنی فائل کے اوپر ایک گلوبل ویریبل بنائیں گے:
let account = null;
جب صارف کا ڈیٹا ایک ویریبل میں محفوظ ہو جاتا ہے تو ہم navigate() فنکشن کا استعمال کرتے ہوئے لاگ ان صفحے سے ڈیش بورڈ پر جا سکتے ہیں۔
آخر میں، ہمیں لاگ ان فارم جمع کرانے پر اپنے login فنکشن کو کال کرنے کی ضرورت ہے، HTML میں ترمیم کرکے:
<form id="loginForm" action="javascript:login()">
یہ چیک کریں کہ سب کچھ صحیح طریقے سے کام کر رہا ہے یا نہیں، ایک نیا اکاؤنٹ رجسٹر کرکے اور اسی اکاؤنٹ کا استعمال کرتے ہوئے لاگ ان کرنے کی کوشش کریں۔
اگلے حصے پر جانے سے پہلے، ہم اپنے register فنکشن کو مکمل کر سکتے ہیں، اس فنکشن کے آخر میں یہ شامل کرکے:
account = result;
navigate('/dashboard');
✅ کیا آپ جانتے ہیں کہ ڈیفالٹ کے طور پر، آپ صرف اسی ڈومین اور پورٹ سے سرور APIs کو کال کر سکتے ہیں جس ویب صفحے کو آپ دیکھ رہے ہیں؟ یہ براؤزرز کے ذریعے نافذ کردہ حفاظتی میکانزم ہے۔ لیکن ٹھہریں، ہماری ویب ایپ localhost:3000 پر چل رہی ہے جبکہ سرور API localhost:5000 پر چل رہا ہے، یہ کیسے کام کرتا ہے؟ Cross-Origin Resource Sharing (CORS) نامی تکنیک کا استعمال کرتے ہوئے، اگر سرور جواب میں مخصوص ڈومینز کے لیے استثنیٰ کی اجازت دینے والے خاص ہیڈرز شامل کرے تو کراس اوریجن HTTP درخواستیں انجام دینا ممکن ہے۔
APIs کے بارے میں مزید جاننے کے لیے یہ سبق لیں۔
HTML کو ڈیٹا دکھانے کے لیے اپ ڈیٹ کریں
اب جب کہ ہمارے پاس صارف کا ڈیٹا موجود ہے، ہمیں موجودہ HTML کو اپ ڈیٹ کرنا ہوگا تاکہ اسے دکھایا جا سکے۔ ہم پہلے ہی جانتے ہیں کہ DOM سے عنصر کو کیسے حاصل کیا جائے، مثال کے طور پر document.getElementById() کا استعمال کرتے ہوئے۔ جب آپ کے پاس ایک بنیادی عنصر ہو، تو یہاں کچھ APIs ہیں جنہیں آپ اسے تبدیل کرنے یا اس میں بچے عناصر شامل کرنے کے لیے استعمال کر سکتے ہیں:
-
textContentپراپرٹی کا استعمال کرتے ہوئے آپ کسی عنصر کے متن کو تبدیل کر سکتے ہیں۔ نوٹ کریں کہ اس ویلیو کو تبدیل کرنے سے عنصر کے تمام بچے (اگر کوئی ہو) ہٹا دیے جاتے ہیں اور اسے فراہم کردہ متن سے تبدیل کر دیا جاتا ہے۔ اس طرح، یہ کسی دیے گئے عنصر کے تمام بچوں کو ہٹانے کا ایک مؤثر طریقہ بھی ہے، خالی سٹرنگ''تفویض کرکے۔ -
document.createElement()کے ساتھappend()طریقہ استعمال کرتے ہوئے آپ ایک یا زیادہ نئے بچے عناصر بنا سکتے ہیں اور منسلک کر سکتے ہیں۔
✅ کسی عنصر کی innerHTML پراپرٹی کا استعمال کرتے ہوئے اس کے HTML مواد کو تبدیل کرنا بھی ممکن ہے، لیکن اس سے گریز کیا جانا چاہیے کیونکہ یہ cross-site scripting (XSS) حملوں کے لیے حساس ہے۔
کام
ڈیش بورڈ اسکرین پر جانے سے پہلے، ہمیں لاگ ان صفحے پر ایک اور کام کرنا چاہیے۔ فی الحال، اگر آپ کسی ایسے صارف نام کے ساتھ لاگ ان کرنے کی کوشش کرتے ہیں جو موجود نہیں ہے، تو کنسول میں ایک پیغام دکھایا جاتا ہے لیکن ایک عام صارف کے لیے کچھ بھی تبدیل نہیں ہوتا اور آپ کو معلوم نہیں ہوتا کہ کیا ہو رہا ہے۔
آئیے لاگ ان فارم میں ایک پلیس ہولڈر عنصر شامل کریں جہاں ضرورت پڑنے پر ہم ایک غلطی کا پیغام دکھا سکیں۔ ایک اچھا مقام لاگ ان <button> سے بالکل پہلے ہوگا:
...
<div id="loginError"></div>
<button>Login</button>
...
یہ <div> عنصر خالی ہے، یعنی جب تک ہم اس میں کچھ مواد شامل نہ کریں، اسکرین پر کچھ بھی ظاہر نہیں ہوگا۔ ہم اسے id بھی دیتے ہیں تاکہ ہم اسے جاوا اسکرپٹ کے ساتھ آسانی سے حاصل کر سکیں۔
app.js فائل پر واپس جائیں اور ایک نیا ہیلپر فنکشن updateElement بنائیں:
function updateElement(id, text) {
const element = document.getElementById(id);
element.textContent = text;
}
یہ کافی سیدھا ہے: دیے گئے عنصر id اور text کے ساتھ، یہ DOM عنصر کے متن کے مواد کو اپ ڈیٹ کرے گا جس کا id مماثل ہوگا۔ آئیے اس طریقہ کو login فنکشن میں پچھلے غلطی کے پیغام کی جگہ استعمال کریں:
if (data.error) {
return updateElement('loginError', data.error);
}
اب اگر آپ کسی غلط اکاؤنٹ کے ساتھ لاگ ان کرنے کی کوشش کرتے ہیں، تو آپ کو کچھ اس طرح نظر آنا چاہیے:
اب ہمارے پاس ایک غلطی کا متن ہے جو بصری طور پر ظاہر ہوتا ہے، لیکن اگر آپ اسے اسکرین ریڈر کے ساتھ آزماتے ہیں تو آپ دیکھیں گے کہ کچھ بھی اعلان نہیں کیا جاتا۔ صفحے پر متحرک طور پر شامل کیے گئے متن کو اسکرین ریڈرز کے ذریعے اعلان کرنے کے لیے، اسے Live Region کا استعمال کرنا ہوگا۔ یہاں ہم ایک مخصوص قسم کے لائیو ریجن کا استعمال کریں گے جسے الرٹ کہا جاتا ہے:
<div id="loginError" role="alert"></div>
رجسٹر فنکشن کی غلطیوں کے لیے بھی یہی رویہ نافذ کریں (HTML کو اپ ڈیٹ کرنا نہ بھولیں)۔
ڈیش بورڈ پر معلومات دکھائیں
ہم نے ابھی جو تکنیکیں دیکھی ہیں ان کا استعمال کرتے ہوئے، ہم ڈیش بورڈ صفحے پر اکاؤنٹ کی معلومات دکھانے کا بھی خیال رکھیں گے۔
یہ وہ ہے جو سرور سے موصول ہونے والا اکاؤنٹ آبجیکٹ دکھائی دیتا ہے:
{
"user": "test",
"currency": "$",
"description": "Test account",
"balance": 75,
"transactions": [
{ "id": "1", "date": "2020-10-01", "object": "Pocket money", "amount": 50 },
{ "id": "2", "date": "2020-10-03", "object": "Book", "amount": -10 },
{ "id": "3", "date": "2020-10-04", "object": "Sandwich", "amount": -5 }
],
}
نوٹ: آپ کی زندگی کو آسان بنانے کے لیے، آپ پہلے سے موجود
testاکاؤنٹ استعمال کر سکتے ہیں جو پہلے ہی ڈیٹا سے بھرا ہوا ہے۔
کام
آئیے HTML میں "Balance" سیکشن کو پلیس ہولڈر عناصر شامل کرنے کے لیے تبدیل کریں:
<section>
Balance: <span id="balance"></span><span id="currency"></span>
</section>
ہم اکاؤنٹ کی تفصیل دکھانے کے لیے نیچے ایک نیا سیکشن بھی شامل کریں گے:
<h2 id="description"></h2>
✅ چونکہ اکاؤنٹ کی تفصیل اس کے نیچے موجود مواد کے لیے ایک عنوان کے طور پر کام کرتی ہے، اسے معنوی طور پر ایک ہیڈنگ کے طور پر نشان زد کیا گیا ہے۔ اس بارے میں مزید جانیں کہ ہیڈنگ اسٹرکچر رسائی کے لیے کیوں اہم ہے، اور صفحے پر تنقیدی نظر ڈالیں تاکہ یہ معلوم کیا جا سکے کہ اور کیا ہیڈنگ ہو سکتی ہے۔
اگلا، ہم app.js میں ایک نیا فنکشن بنائیں گے تاکہ پلیس ہولڈر کو بھر سکیں:
function updateDashboard() {
if (!account) {
return navigate('/login');
}
updateElement('description', account.description);
updateElement('balance', account.balance.toFixed(2));
updateElement('currency', account.currency);
}
سب سے پہلے، ہم چیک کرتے ہیں کہ ہمارے پاس مطلوبہ اکاؤنٹ ڈیٹا موجود ہے یا نہیں۔ پھر ہم HTML کو اپ ڈیٹ کرنے کے لیے پہلے سے بنائے گئے updateElement() فنکشن کا استعمال کرتے ہیں۔
بیلنس ڈسپلے کو مزید خوبصورت بنانے کے لیے، ہم
toFixed(2)طریقہ استعمال کرتے ہیں تاکہ ویلیو کو اعشاریہ کے بعد 2 ہندسوں کے ساتھ دکھانے پر مجبور کیا جا سکے۔
اب ہمیں ہر بار ڈیش بورڈ لوڈ ہونے پر اپنے updateDashboard() فنکشن کو کال کرنے کی ضرورت ہے۔ اگر آپ نے پہلے ہی سبق 1 کا اسائنمنٹ مکمل کر لیا ہے تو یہ سیدھا ہونا چاہیے، ورنہ آپ درج ذیل نفاذ استعمال کر سکتے ہیں۔
یہ کوڈ updateRoute() فنکشن کے آخر میں شامل کریں:
if (typeof route.init === 'function') {
route.init();
}
اور روٹس کی تعریف کو اپ ڈیٹ کریں:
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard', init: updateDashboard }
};
اس تبدیلی کے ساتھ، ہر بار جب ڈیش بورڈ صفحہ دکھایا جاتا ہے، تو فنکشن updateDashboard() کال کیا جاتا ہے۔ لاگ ان کے بعد، آپ کو اکاؤنٹ بیلنس، کرنسی اور تفصیل دیکھنے کے قابل ہونا چاہیے۔
HTML ٹیمپلیٹس کے ساتھ ٹیبل کی قطاریں متحرک طور پر بنائیں
پہلے سبق میں ہم نے نیویگیشن کو اپنی ایپ میں نافذ کرنے کے لیے HTML ٹیمپلیٹس کے ساتھ appendChild() طریقہ استعمال کیا۔ ٹیمپلیٹس چھوٹے بھی ہو سکتے ہیں اور صفحے کے بار بار آنے والے حصے کو متحرک طور پر بھرنے کے لیے استعمال کیے جا سکتے ہیں۔
ہم HTML ٹیبل میں لین دین کی فہرست دکھانے کے لیے اسی طرح کا طریقہ استعمال کریں گے۔
کام
HTML <body> میں ایک نیا ٹیمپلیٹ شامل کریں:
<template id="transaction">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</template>
یہ ٹیمپلیٹ ایک واحد ٹیبل قطار کی نمائندگی کرتا ہے، جس میں وہ 3 کالم ہیں جنہیں ہم بھرنا چاہتے ہیں: لین دین کی تاریخ، آبجیکٹ اور رقم۔
پھر، ٹیبل کے <tbody> عنصر میں یہ id پراپرٹی شامل کریں تاکہ اسے جاوا اسکرپٹ کا استعمال کرتے ہوئے تلاش کرنا آسان ہو:
<tbody id="transactions"></tbody>
ہمارا HTML تیار ہے، آئیے جاوا اسکرپٹ کوڈ پر سوئچ کریں اور ایک نیا فنکشن createTransactionRow بنائیں:
function createTransactionRow(transaction) {
const template = document.getElementById('transaction');
const transactionRow = template.content.cloneNode(true);
const tr = transactionRow.querySelector('tr');
tr.children[0].textContent = transaction.date;
tr.children[1].textContent = transaction.object;
tr.children[2].textContent = transaction.amount.toFixed(2);
return transactionRow;
}
یہ فنکشن بالکل وہی کرتا ہے جو اس کے نام سے ظاہر ہوتا ہے: ہم نے پہلے بنائے گئے ٹیمپلیٹ کا استعمال کرتے ہوئے، یہ ایک نئی ٹیبل قطار بناتا ہے اور لین دین کے ڈیٹا کا استعمال کرتے ہوئے اس کے مواد کو بھرتا ہے۔ ہم اپنے updateDashboard() فنکشن میں ٹیبل کو بھرنے کے لیے اس کا استعمال کریں گے:
const transactionsRows = document.createDocumentFragment();
for (const transaction of account.transactions) {
const transactionRow = createTransactionRow(transaction);
transactionsRows.appendChild(transactionRow);
}
updateElement('transactions', transactionsRows);
یہاں ہم document.createDocumentFragment() طریقہ استعمال کرتے ہیں جو ایک نیا DOM فریگمنٹ بناتا ہے جس پر ہم کام کر سکتے ہیں، آخر میں اسے اپنے HTML ٹیبل سے جوڑنے سے پہلے۔
اس کوڈ کے کام کرنے سے پہلے ہمیں ایک اور کام کرنا ہوگا، کیونکہ ہمارا updateElement() فنکشن فی الحال صرف متن کے مواد کو سپورٹ کرتا ہے۔ آئیے اس کے کوڈ کو تھوڑا سا تبدیل کریں:
function updateElement(id, textOrNode) {
const element = document.getElementById(id);
element.textContent = ''; // Removes all children
element.append(textOrNode);
}
ہم append() میتھڈ استعمال کرتے ہیں کیونکہ یہ ہمیں متن یا DOM Nodes کو پیرنٹ عنصر کے ساتھ جوڑنے کی اجازت دیتا ہے، جو ہمارے تمام استعمال کے لیے بہترین ہے۔
اگر آپ test اکاؤنٹ استعمال کرکے لاگ ان کرنے کی کوشش کریں، تو آپ کو اب ڈیش بورڈ پر ٹرانزیکشن لسٹ نظر آئے گی 🎉۔
GitHub Copilot Agent Challenge 🚀
ایجنٹ موڈ استعمال کریں تاکہ درج ذیل چیلنج مکمل کیا جا سکے:
تفصیل: بینکنگ ایپ کو بہتر بنائیں اور ایک ٹرانزیکشن سرچ اور فلٹر فیچر نافذ کریں جو صارفین کو تاریخ کی حد، رقم، یا تفصیل کے ذریعے مخصوص ٹرانزیکشنز تلاش کرنے کی اجازت دے۔
پرومپٹ: بینکنگ ایپ کے لیے ایک سرچ فنکشنلٹی بنائیں جس میں شامل ہو: 1) ایک سرچ فارم جس میں تاریخ کی حد (سے/تک)، کم سے کم/زیادہ سے زیادہ رقم، اور ٹرانزیکشن تفصیل کے کلیدی الفاظ کے لیے ان پٹ فیلڈز ہوں، 2) ایک filterTransactions() فنکشن جو اکاؤنٹ.transactions array کو سرچ کے معیار کے مطابق فلٹر کرے، 3) updateDashboard() فنکشن کو اپ ڈیٹ کریں تاکہ فلٹر شدہ نتائج دکھائے جا سکیں، اور 4) "Clear Filters" بٹن شامل کریں تاکہ ویو کو ری سیٹ کیا جا سکے۔ جدید جاوا اسکرپٹ array میتھڈز جیسے filter() استعمال کریں اور خالی سرچ معیار کے لیے edge cases کو ہینڈل کریں۔
🚀 چیلنج
مل کر کام کریں تاکہ ڈیش بورڈ پیج کو ایک حقیقی بینکنگ ایپ کی طرح دکھایا جا سکے۔ اگر آپ نے پہلے ہی اپنی ایپ کو اسٹائل کیا ہے، تو کوشش کریں کہ میڈیا کوئریز استعمال کریں تاکہ ایک ریسپانسیو ڈیزائن بنایا جا سکے جو ڈیسک ٹاپ اور موبائل دونوں پر اچھا کام کرے۔
یہاں ایک اسٹائلڈ ڈیش بورڈ پیج کی مثال ہے:
لیکچر کے بعد کا کوئز
اسائنمنٹ
اپنے کوڈ کو ریفیکٹر کریں اور اس پر تبصرہ کریں
اعلانِ لاتعلقی:
یہ دستاویز AI ترجمہ سروس Co-op Translator کا استعمال کرتے ہوئے ترجمہ کی گئی ہے۔ ہم درستگی کے لیے کوشش کرتے ہیں، لیکن براہ کرم آگاہ رہیں کہ خودکار ترجمے میں غلطیاں یا غیر درستیاں ہو سکتی ہیں۔ اصل دستاویز کو اس کی اصل زبان میں مستند ذریعہ سمجھا جانا چاہیے۔ اہم معلومات کے لیے، پیشہ ور انسانی ترجمہ کی سفارش کی جاتی ہے۔ اس ترجمے کے استعمال سے پیدا ہونے والی کسی بھی غلط فہمی یا غلط تشریح کے لیے ہم ذمہ دار نہیں ہیں۔



