How To Fix object.map ليس خطأ وظيفي في JavaScript
نشرت: 2022-04-10تخيل هذا: لقد حصلت على إعداد استدعاء API وتعمل. تعود البيانات مع ما كنت تتوقعه. الآن؟ حان الوقت للعمل مع هذه البيانات لإنشاء الحل الذي تبحث عنه. فجأة ، ترى خطأ في وحدة التحكم الخاصة بك.
ماذا حدث ، ولماذا ترى أن object.map is not a function
؟ تابع القراءة لمعرفة ذلك.
المشكلة
سبب الخطأ في الواقع بسيط للغاية: طريقة .map()
قابلة للتطبيق فقط عند العمل مع المصفوفات. وبشكل أكثر تحديدًا ، توجد الطريقة في النموذج الأولي للصفيف Array
Array.prototype.map()
.
تم تقديم هذه الطريقة في الأصل في عام 2009 مع ES5 وهي مفيدة جدًا في العديد من السيناريوهات. Array.map()
يأخذ دالة رد الاتصال كمعامل واحد فقط. يتم إعطاء رد النداء هذا معاملين: العنصر الحالي وفهرسه في المصفوفة. تعمل الطريقة نفسها بشكل مشابه لاستدعاء Array.forEach()
باستثناء قيم الإرجاع الخاصة برد النداء التي يتم تجميعها معًا في مصفوفة جديدة يتم إرجاعها بواسطة الطريقة نفسها.
يعد إنشاء مصفوفة جديدة من مصفوفة معينة طريقة للحفاظ على الثبات في كود JavaScript الخاص بك. من المهم ملاحظة أنه إذا كنت تستخدم Array.map()
على مصفوفة من الكائنات وقمت بتغيير خاصية على كائن معين ، فقد تم تغيير هذا الكائن الآن. لتجنب ذلك يمكنك إنشاء نسخة من الكائن أولاً ثم تعديل النسخة.
على سبيل المثال ، إذا كان لديك مصفوفة من الأرقام وتريد إنشاء مصفوفة جديدة حيث يتم مضاعفة كل رقم في المصفوفة الأصلية ، يمكنك ببساطة القيام بذلك:
const items = [ 1 , 2 , 3 ]; // ES5 approach const doubledItems = items.map( function ( item ) { return item * 2 ; }); // ES6+ approach const doubledItems = items.map( ( item ) => { return item * 2 ; }); // Least code approach const doubledItems = items.map( ( item ) => item * 2 ); console .log(doubledItems); // [2, 4, 6]
لغة الكود: جافا سكريبت ( جافا سكريبت )
الحل
لحل object.map is not a function
، اكتشف أولاً شكل البيانات التي تعمل بها ثم قم بإنشاء مصفوفة من تلك البيانات بناءً على ماهية البيانات. على سبيل المثال ، ربما تكون بياناتك كائنًا بسيطًا ولكن المصفوفة التي تبحث عنها موجودة بالفعل داخل هذا الكائن. في هذه الحالة ، ما عليك سوى استخدام رمز النقطة للوصول إلى الخاصية المطلوبة:
const object = { items : [ { id : 1 , data : "item 1 data" , }, { id : 2 , data : "item 2 data" , }, ], }; const error = object.map( ( item ) => item.data); // This will cause your error! // Instead, map over the items property rather than the parent object const result = object.items.map( ( item ) => item.data); console .log(result); // ["item 1 data", "item 2 data"]
لغة الكود: جافا سكريبت ( جافا سكريبت )
من الممكن أيضًا أن تكون بياناتك كائنًا بسيطًا ولكن البيانات التي ترغب في تكرارها مخزنة في كل مفتاح في الكائن. في هذه الحالة ، يمكنك تكرار هذه المفاتيح وتنفيذ منطقك على القيمة الخاصة بكل مفتاح:
const object = { 1 : { id : "1" , data : "item 1 data" , }, 2 : { id : "2" , data : "item 2 data" , }, }; const error = object.map( ( item ) => item.data); // This will cause your error! // Get an array of the keys in your object const array = Object .keys(object); // [1, 2] // Loop through that array using each key to get the value const result = array.map( ( key ) => { const value = object[key]; // Perform your desired logic here then return a new value return value.data; }); console .log(result); // ["item 1 data", "item 2 data"]
لغة الكود: جافا سكريبت ( جافا سكريبت )
هناك حاجة إلى حل شائع آخر عند العمل باستخدام Set
أو Map
JavaScript. نظرًا لأن كلاهما قابل للتكرار ولهما طريقة .forEach()
، فقد تفترض بشكل معقول أن .map()
سيعمل أيضًا. نظرًا لأنها ليست صفائف تقنيًا ، فستحتاج إلى حل بديل. الحل مشابه لكل من Set
أو Map
ولدينا أيضًا مقال يشرح كيفية التعامل مع قيمها بمزيد من التفاصيل والتي يمكنك عرضها هنا.
// --- Map solution example --- const myMap = new Map (); myMap.set( 1 , "item 1 data" ); myMap.set( 2 , "item 2 data" ); const myMapError = myMap.map(); // This will cause your error! // Create an array from the values of the Map const myMapArray = [...myMap.values()]; const myMapResult = myMapArray.map( ( item ) => { // Perform your logic here if (item) { return item; } }); console .log(myMapResult); // ["item 1 data", "item 2 data"] // --- Set solution example --- const mySet = new Set (); mySet.add( "item 1 data" ); mySet.add( "item 2 data" ); // Since set values are unique this won't be added to the Set mySet.add( "item 2 data" ); const mySetError = mySet.map(); // This will cause your error! const mySetArray = [...mySet.values()]; const mySetResult = mySetArray.map( ( item ) => { // Perform your logic here if (item) { return item; } }); console .log(mySetResult); // ["item 1 data", "item 2 data"]
لغة الكود: جافا سكريبت ( جافا سكريبت )
إذا كنت ترغب في تجنب الخطأ في المستقبل ، خاصةً إذا كنت لا تعرف الشكل الدقيق للبيانات التي ستحاول استدعاء Array.map()
عليها ، فإليك وظيفة بسيطة لتعيين قيم المصفوفة بأمان:
const safelyMap = ( data, callback ) => { if (!(data && Array .isArray(data))) { return []; } return data.map(callback); }; // Arbitrary callback function const callback = ( item ) => item; console .log(safelyMap( null , callback)); // [] console .log(safelyMap( new Set (), callback)); // [] console .log(safelyMap([ 1 , 2 , 3 ], callback)); // [1, 2, 3]
لغة الكود: جافا سكريبت ( جافا سكريبت )
نأمل أن يحل أحد هذه الحلول حالتك المحددة ، ولكن إذا لم يكن الأمر كذلك ، فيرجى ترك تعليق وسنكون سعداء لمساعدتك.