TypeError: Cannot read properties of undefined (reading 'x')জাভাস্ক্রিপ্টের সবচেয়ে সাধারণ রানটাইম ত্রুটি। একবার আপনি এটি পড়তে শিখলে বার্তাটি সুনির্দিষ্ট হয়, এবং সংশোধন প্রায় সবসময়ই পাঁচটি প্যাটার্নের মধ্যে একটি। এই নির্দেশিকাটি কভার করে যে কীভাবে দ্রুত কারণটি সনাক্ত করা যায় এবং কীভাবে এটি পুনরাবৃত্ত হওয়া বন্ধ করা যায়।
📋 Table of Contents
- ত্রুটি আসলে কি মানে
- কারণ 1: Async ডেটা আসার আগে পড়ুন
- আপনি লিখেছেন
- ফিরে আসে
- Destructuring বৈশিষ্ট্যগুলি পড়ে, তাই এটি ঠিক একই কারণে নিক্ষেপ করে — শুধু একটি কম সুস্পষ্ট স্ট্যাক লাইন সহ।
- এর বাঁধন হারিয়েছেthisযখন একটি পদ্ধতি একটি কলব্যাক হিসাবে পাস করা হয়,
- ঐচ্ছিক চেইনিং
- ত্রুটি প্রদর্শিত হলে, এই ক্রম মাধ্যমে কাজ.
- টাইপস্ক্রিপ্ট
- প্রশ্ন: এটি এবং "নালের বৈশিষ্ট্যগুলি পড়তে পারে না" এর মধ্যে পার্থক্য কী?
- উপসংহার
ত্রুটি আসলে কি মানে
আপনি এমন কিছু থেকে একটি সম্পত্তি পড়ার চেষ্টা করেছেন যা হলundefined. বন্ধনীর অংশটি আপনাকে বলে যে আপনি কোন সম্পত্তি পড়ার চেষ্টা করেছেন।
const user = undefined;
console.log(user.name);
// TypeError: Cannot read properties of undefined (reading 'name')
সমালোচনামূলক অন্তর্দৃষ্টি:সমস্যাটি সম্পত্তি নয়, এটি বিন্দুর আগে জিনিস। যখন দেখবে(reading 'name'), বাগ হল যে ব্যবহারকারীর অবজেক্টে যা রাখা উচিত ছিল তা হলundefined. সবাই সময় ডিবাগিং হারায়name যখন তাদের জিজ্ঞাসা করা উচিত কেনuser খালি
একটি শৃঙ্খলে, প্রথম অনির্ধারিত লিঙ্ক খুঁজে পেতে বাম থেকে ডানে কাজ করুন।
const response = { data: { items: [] } };
console.log(response.data.results.length);
// TypeError: Cannot read properties of undefined (reading 'length')
// 'results' does not exist on data, so response.data.results is undefined.
কারণ 1: Async ডেটা আসার আগে পড়ুন
বাস্তব অ্যাপ্লিকেশনের মধ্যে সবচেয়ে ঘন ঘন কারণ. রাজ্য খালি শুরু হয়, রেন্ডার চলে, এবং আনার এখনও সমাধান হয়নি৷
function Profile({ userId }) {
const [user, setUser] = useState(); // undefined on first render
useEffect(() => {
fetch(`/api/users/${userId}`)
.then(r => r.json())
.then(setUser);
}, [userId]);
return <h1>{user.name}</h1>; // throws on the very first render
}
একটি বোধগম্য খালি মান শুরু করে এবং রেন্ডার রক্ষা করে ঠিক করুন।
function Profile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
setLoading(true);
fetch(`/api/users/${userId}`)
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
})
.then(data => { if (!cancelled) setUser(data); })
.catch(err => { if (!cancelled) console.error(err); })
.finally(() => { if (!cancelled) setLoading(false); });
return () => { cancelled = true; };
}, [userId]);
if (loading) return <p>Loading…</p>;
if (!user) return <p>User not found.</p>;
return <h1>{user.name}</h1>;
}
পতাকা একটি দ্বিতীয় সাধারণ বাগ প্রতিরোধ করে: পূর্ববর্তী থেকে একটি ধীর প্রতিক্রিয়াcancelled প্রপ পরিবর্তিত হওয়ার পরে নতুন ডেটা ওভাররাইট করা হচ্ছে।userIdকারণ 2: API রেসপন্স আকৃতি আপনি যা ধরেছেন তা নয়
আপনি লিখেছেন
কিন্তু API ফিরে আসেdata.items, অথবা এটি সব কিছুকে মুড়ে দেয়{ results: [...] }. এটি Axios এর সাথে ভুল করা বিশেষত সহজ, যা এর নিজস্ব{ data: { ... } }যোগ করে৷ প্রতিক্রিয়া শরীরের উপরে মোড়ানো.dataএটিতে ইন্ডেক্স করার আগে পুরো প্রতিক্রিয়াটি লগ করুন। এক
// Axios puts the response body in .data — so the payload is often data.data
const response = await axios.get('/api/users');
console.log(response.data.users); // correct
console.log(response.users); // undefined -> throws downstream
অবিলম্বে প্রশ্নের উত্তর দেয়, যেখানে অনুমান করা যায় না।console.log(JSON.stringify(response, null, 2))কারণ 3: অ্যারে অনুসন্ধান পদ্ধতি যা কিছুই খুঁজে পায়নি
ফিরে আসে
find যখন কোনো উপাদান মেলে না, এবং এটি তালিকা-হ্যান্ডলিং কোডে ত্রুটির একক সবচেয়ে সাধারণ উৎস।undefinedসর্বদা ফলাফলটিকে সম্ভবত অনুপস্থিত হিসাবে বিবেচনা করুন।
const users = [{ id: 1, name: 'Ada' }];
const match = users.find(u => u.id === 99);
console.log(match.name);
// TypeError: Cannot read properties of undefined (reading 'name')
একই কথা প্রযোজ্য
const match = users.find(u => u.id === 99);
if (!match) {
return null; // or throw a clear domain error
}
console.log(match.name);
// Or with optional chaining when a missing value is acceptable:
console.log(match?.name ?? 'Unknown user');
, যা ফিরে আসেdocument.querySelector যখন কিছুই মেলে না, এবংnull এবংMap.getকারণ 4: একটি অনির্ধারিত বস্তুকে ধ্বংস করাArray.at.
Destructuring বৈশিষ্ট্যগুলি পড়ে, তাই এটি ঠিক একই কারণে নিক্ষেপ করে — শুধু একটি কম সুস্পষ্ট স্ট্যাক লাইন সহ।
প্যারামিটারটিকে একটি ডিফল্ট দিন যাতে ধ্বংসের সাথে কাজ করার জন্য সর্বদা একটি বস্তু থাকে।
function greet({ name }) {
return `Hello ${name}`;
}
greet();
// TypeError: Cannot destructure property 'name' of 'undefined'
কারণ 5:
function greet({ name = 'friend' } = {}) {
return `Hello ${name}`;
}
greet(); // "Hello friend"
greet({ name: 'Ada' }); // "Hello Ada"
এর বাঁধন হারিয়েছেthisযখন একটি পদ্ধতি একটি কলব্যাক হিসাবে পাস করা হয়,
এটি আর অবজেক্ট নয়, তাই এটিতে পড়া প্রতিটি সম্পত্তি ব্যর্থ হয়।thisএটি আবদ্ধ করুন, অথবা একটি তীর ফাংশন সহ একটি ক্লাস ক্ষেত্র ব্যবহার করুন, যা ক্যাপচার করে
class Counter {
constructor() { this.count = 0; }
increment() { this.count++; } // 'this' is undefined when detached
}
const c = new Counter();
button.addEventListener('click', c.increment);
// TypeError: Cannot read properties of undefined (reading 'count')
আভিধানিকভাবেthisএটি প্রতিরোধকারী সরঞ্জামগুলি
class Counter {
count = 0;
increment = () => { this.count++; }; // arrow field — always bound
}
const c = new Counter();
button.addEventListener('click', c.increment); // works
ঐচ্ছিক চেইনিং
শর্ট সার্কিট থেকে নিক্ষেপ করার পরিবর্তে।undefinedশূন্য কোলেসিং
const city = user?.address?.city; // undefined, no throw
const first = users?.[0]?.name; // works on arrays too
const result = api.getUser?.(id); // and on possibly-missing methods
শুধুমাত্রএর জন্য একটি ফলব্যাক সরবরাহ করে৷ এবংnull, অসদৃশundefined যা প্রতিস্থাপন করে|| এবং খালি স্ট্রিং।0ঐচ্ছিক চেইনিং ব্যবহার করুন যেখানে একটি অনুপস্থিত মান প্রকৃতপক্ষে বৈধ। ত্রুটিগুলি নীরব করার জন্য এটিকে সর্বত্র ছড়িয়ে দেবেন না — যদি
const count = data?.count ?? 0; // 0 stays 0
const wrong = data?.count || 0; // a real 0 becomes 0 anyway, but '' becomes 0 too
সর্বদা সেই বিন্দুতে বিদ্যমান থাকা উচিত, এর অনুপস্থিতি লুকিয়ে রাখলে একটি উচ্চস্বরে বাগকে একটি নীরবতায় পরিণত করে যা পরবর্তীতে কোন স্ট্যাক ট্রেস ছাড়াই দেখা যায়।userডিবাগিং পদ্ধতি
ত্রুটি প্রদর্শিত হলে, এই ক্রম মাধ্যমে কাজ.
বন্ধনীতে সম্পত্তির নাম পড়ুন। বাগটি অভিব্যক্তিতে রয়েছে
- আগে যে সম্পত্তিস্ট্যাক ট্রেস খুলুন এবং লাইব্রেরি ফ্রেম উপেক্ষা করে আপনার নিজের কোডের শীর্ষস্থানীয় ফ্রেমে ক্লিক করুন।
- সেই লাইনে একটি ব্রেকপয়েন্ট সেট করুন এবং সম্বলিত অভিব্যক্তিটি পরিদর্শন করুন, সম্পত্তি নয়।
- অনির্ধারিত প্রথম লিঙ্কটি খুঁজে পেতে চেইনটি বাম থেকে ডানে হাঁটুন।
- জিজ্ঞাসা করুন কেন সেই মান খালি — একটি আনা কি সমাধান হয়নি, একটি অনুসন্ধান মিস করেছে, একটি প্রপ কি কখনও পাস হয়নি?
- উৎপাদনে, উৎস মানচিত্র অপরিহার্য। তাদের ছাড়া মিনিফাইড কোডে ট্রেস পয়েন্ট এবং এই প্রক্রিয়াটি অসম্ভব।
এটি গঠনগতভাবে প্রতিরোধ করা
টাইপস্ক্রিপ্ট
কম্পাইলের সময়ে এইগুলির বেশিরভাগই ধরা পড়ে, বিশেষ করেএর সাথে সক্রিয় কোড চলার আগে এটি আপনাকে অনির্ধারিত কেস পরিচালনা করতে বাধ্য করে।strictNullChecksসীমানায় যাচাই করুন।
function getName(user: User | undefined): string {
// Error: 'user' is possibly 'undefined' — caught before runtime
return user.name;
}
Zod-এর মতো স্কিমা ভ্যালিডেটর দিয়ে API প্রতিক্রিয়াগুলিকে পার্স করুন যাতে আপনার রেন্ডারিং কোডে একটি অনির্ধারিত তিনটি স্তর প্রচার করার পরিবর্তে একটি অপ্রত্যাশিত আকার একটি পরিষ্কার বার্তা সহ অবিলম্বে ব্যর্থ হয়।খালি সংগ্রহ ফেরত দিন, অনির্ধারিত নয়।
একটি ফাংশন যা রিটার্ন করে পরিবর্তে[] কলারদের ফলাফলের উপর শর্তহীনভাবে ম্যাপ করতে দেয়।undefinedপ্রায়শই জিজ্ঞাসিত প্রশ্ন
প্রশ্ন: এটি এবং “নালের বৈশিষ্ট্যগুলি পড়তে পারে না” এর মধ্যে পার্থক্য কী?
উত্তর: শুধুমাত্র মান।
সাধারণত একটি পরিবর্তনশীল বরাদ্দ করা হয় নি বা একটি সম্পত্তি বিদ্যমান নেই মানে; undefined সাধারণত কিছু মানে স্পষ্টভাবে এটি খালি সেট করা। ডিবাগিং পদ্ধতি অভিন্ন।nullপ্রশ্ন: আমার কি সব জায়গায় ঐচ্ছিক চেইনিং যোগ করা উচিত?
প্রশ্ন: আমার কি সব জায়গায় ঐচ্ছিক চেইনিং যোগ করা উচিত?
উত্তর: না। এটি ব্যবহার করুন যেখানে একটি মান বৈধভাবে ঐচ্ছিক। আপনি বুঝতে পারেন না এমন একটি ত্রুটিকে নীরব করার জন্য এটি ব্যবহার করা স্ট্যাক ট্রেস সহ একটি ক্র্যাশকে কোনও ট্রেস ছাড়াই ভুল আচরণে রূপান্তরিত করে।
প্রশ্নঃ কেন এটি স্থানীয়ভাবে কাজ করে কিন্তু উৎপাদনে ব্যর্থ হয়?
উত্তর: সাধারণত সময় বা ডেটা। স্থানীয় APIগুলি দ্রুত সাড়া দেয়, তাই রেসের অবস্থা লুকিয়ে থাকে; এবং প্রোডাকশন ডেটাতে এমন আকার রয়েছে যা আপনার পরীক্ষার ডেটা নেই, যেমন অনুপস্থিত ঐচ্ছিক ক্ষেত্র সহ রেকর্ড।
প্রশ্ন: স্ট্যাক ট্রেস শুধুমাত্র লাইব্রেরি কোড দেখালে আমি কীভাবে ত্রুটি খুঁজে পাব?
উত্তর: সোর্স ম্যাপগুলি সক্ষম করুন, তারপরে ফ্রেমওয়ার্ক ফ্রেমগুলি লুকানোর জন্য Chrome DevTools-এ “উপেক্ষা তালিকা” ব্যবহার করুন যাতে সর্বোচ্চ দৃশ্যমান ফ্রেমটি আপনার নিজের কোড হয়৷
প্রশ্ন: টাইপস্ক্রিপ্ট কি এই ত্রুটিটি সম্পূর্ণরূপে দূর করে?
উত্তর: না। এটি যাচাই করতে পারে এমন কোডের জন্য এটিকে সরিয়ে দেয়, কিন্তু ডেটা ক্রসিং রানটাইম সীমানা — API প্রতিক্রিয়া, JSON পার্সিং,any casts — এখনও রানটাইমে অনির্ধারিত হতে পারে। এমনকি TypeScript এ বহিরাগত ডেটা যাচাই করুন।
উপসংহার
ফিক্সিংCannot read properties of undefined যান্ত্রিক একবার আপনি নিয়ম জানেন:ত্রুটিটি সম্পত্তির আগে অভিব্যক্তিতে রয়েছে, সম্পত্তি নিজেই নয়। পাঁচটি সাধারণ কারণ পরীক্ষা করুন — অ্যাসিঙ্ক ডেটা খুব তাড়াতাড়ি পড়া, একটি অমিল API আকৃতি, একটি যা কিছুই মেলে না, একটি অনুপস্থিত বস্তুকে ধ্বংস করে এবং একটি হারিয়ে যায়find বাঁধাই তারপরে ঐচ্ছিক চেইনিং দিয়ে পুনরাবৃত্তি প্রতিরোধ করুন যেখানে মানগুলি প্রকৃতপক্ষে ঐচ্ছিক, টাইপস্ক্রিপ্ট সঙ্গেthis, এবং প্রতিটি সীমানায় স্কিমা যাচাইকরণ যেখানে বাহ্যিক ডেটা আপনার সিস্টেমে প্রবেশ করে।strictNullChecks, এবং প্রতিটি সীমানায় স্কিমা যাচাইকরণ যেখানে বাহ্যিক ডেটা আপনার সিস্টেমে প্রবেশ করে।
🔗 Share this article
✍️ Leave a Comment