最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Splicing first object returns TypeError: Cannot read property of undefined - Stack Overflow

programmeradmin1浏览0评论

I have an array like this:

var arrSession = [ { name: 'Product 01', groupID: '50303', delivery: 'mail'}, { name: 'Product 02', groupID: '50403', delivery: 'bike'} ]

And this Loop to delete specific objects:

for(var i=0, len=arrSession.length; i<len; i++) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
    }
}

If I'm deleting the last object, all works fine:

var getGroupID = 50403;
var getDelivery = bike;

But if I'm deleting the first object:

var getGroupID = 50303;
var getDelivery = mail;

I get an error:

TypeError: Cannot read property 'groupID' of undefined  

Why so and how to solve it?

Edit:

If there is only one object all is fine too.

var arrSession = [ { name: 'Product 01', groupID: '50303', delivery: 'mail'} ]

I have an array like this:

var arrSession = [ { name: 'Product 01', groupID: '50303', delivery: 'mail'}, { name: 'Product 02', groupID: '50403', delivery: 'bike'} ]

And this Loop to delete specific objects:

for(var i=0, len=arrSession.length; i<len; i++) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
    }
}

If I'm deleting the last object, all works fine:

var getGroupID = 50403;
var getDelivery = bike;

But if I'm deleting the first object:

var getGroupID = 50303;
var getDelivery = mail;

I get an error:

TypeError: Cannot read property 'groupID' of undefined  

Why so and how to solve it?

Edit:

If there is only one object all is fine too.

var arrSession = [ { name: 'Product 01', groupID: '50303', delivery: 'mail'} ]
Share Improve this question asked Jun 19, 2020 at 17:24 Philipp MPhilipp M 3,5085 gold badges43 silver badges101 bronze badges
Add a ment  | 

5 Answers 5

Reset to default 1

Short Answer: Due to the for loop syntax. Initialization happens only once. You missed to update len after splicing.

for ([initialExpression]; [condition]; [incrementExpression]) statement

Solution: As already mentioned in the other answers, you can break the loop (which will work if you are spicing only one item).

const arrSessionActual = [{
  name: 'Product 01',
  groupID: '50303',
  delivery: 'mail'
}, {
  name: 'Product 02',
  groupID: '50403',
  delivery: 'bike'
}];

function removeItem(arrSession, getGroupID, getDelivery) {
  for (var i = 0,
      len = arrSession.length; i < len; i++) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
      arrSession.splice(i, 1);
      len = arrSession.length; // This is missing
    }
  }

  console.log(arrSession);
}

removeItem(arrSessionActual.slice(), 50403, 'bike');
removeItem(arrSessionActual.slice(), 50303, 'mail');

I think this is because when the loop starts, it will go up to index 1. After you delete index 0, your loop will still try to run and search for index 1, the second object, which has already been moved. If you put a break keyword in the if statement, the error should be fixed.

for(var i=0, len=arrSession.length; i<len; i++) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
        break;
    }
}

Pretty simple, you iterate from the start of the array and you splice the array on found. The array is now shorter than the stored length and any access goes wrong.

You could loop from the end instead.

var arrSession = [{ name: 'Product 01', groupID: '50303', delivery: 'mail' }, { name: 'Product 02', groupID: '50403', delivery: 'bike' }],
    getGroupID = 50303,
    getDelivery = 'mail',
    i = arrSession.length;

while (i--) {
    if (arrSession[i].groupID == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
    }
}

console.log(arrSession);

Try it converting 'groupId' to integer format.

ex-:

for(var i=0, len=arrSession.length; i<len; i++) {
    if (parseInt(arrSession[i].groupID) == getGroupID && arrSession[i].delivery == getDelivery) {
        arrSession.splice(i, 1);
    }
}

Array.splice mutates the array. If you remove the first element, the array length decreases by 1 but in the loop it still tries to access the next element which may or may not be undefined. Here since there are only 2 elements the arrSession[1] is undefined.

Instead use filter like this :

var arrSession = [{
  name: 'Product 01',
  groupID: '50303',
  delivery: 'mail'
}, {
  name: 'Product 02',
  groupID: '50403',
  delivery: 'bike'
}]


var getGroupID = 50303;
var getDelivery = 'mail';



var filtered = arrSession.filter(session => session.id !== getGroupID && session.delivery !== getDelivery)

console.log(filtered)

Hope this helps !

发布评论

评论列表(0)

  1. 暂无评论