Eric
Eric

Reputation: 58

Why is .detach() throwing error in array of DOM elements?

I'm wondering why I'm getting error "$groceryItems[i].detach is not a function" when I'm able to see that $groceryItems[i] is indeed a DOM element as a result of logging it?

I have only included the script and not the ejs view.

<script>
function sortByAvgRating() {

var $groceryItems = $('.groceryItems');//grab all of the grocery items

for (var i = $groceryItems.length; i--; ) {//detach each grocery item from the DOM
    console.log('$groceryItems[i] ', $groceryItems[i]);
    $groceryItems[i].detach();
}

$groceryItems.sort(function(a, b) {//sort the grocery items by the rating attribute
    return +a.children[1].children[0].children[0].dataset.rating - 
        +b.children[1].children[0].children[0].dataset.rating;
}).
appendTo('groceryItemsContainer');//apppend the sorted array of elements to the DOM
}

</script>

Upvotes: 1

Views: 135

Answers (2)

ibrahim mahrir
ibrahim mahrir

Reputation: 31712

$groceryItems is a jQuery object that has the function detach defined on it, but $groceryItems[i] is the raw DOM element at the index i. DOM elements don't have a function called detach.

Wrap the element in a jQuery object before calling detach:

$( $groceryItems[i] ).detach();

Or use eq instead of [] (eq will return a jQuery object that has detach defined on it):

$groceryItems.eq(i).detach();
//           ^^^^^^

Upvotes: 0

Barmar
Barmar

Reputation: 782064

@ibrahim mahir's answer explains why your code doesn't work.

But you don't need to write a loop to detach all the elements in a jQuery object. When you apply jQuery modification functions to a collection, it automatically performs it on all elements.

So you can simply write:

$groceryItems.detach();

And when you want to loop over the elements in a collection, use .each():

$groceryItems.each(function() {
    console.log(this);
    $(this).detach();
});

Upvotes: 1

Related Questions