JQuery: Loop through elements and set as variable for outside scope



I am trying to retrieve a DOM element from an array, and I want to set it as a variable to use outside its scope. Right now, my variable future_devices returns one object as expected. But my other variable future_device returns the object when the current DOM should have returned [] due to my last if statement. I originally tried to declare my variables as var due to scope but that did not help. Here is my code:

var future_devices = $('.hardware .future-hardware')

if (future_devices.length) {

  let future_device = $(future_devices)
    .each(function() {

      let device = this
      let device_work_order = $(device)
        .data(
          'work-order'
        )

      if (device_work_order == data['new_host']['work_order']) {

        return device

      }

    })

I can tell you on the said DOM, the two variables I am using to compare have the following values:

device_work_order = 3MOD0

data[‘new_host’][‘work_order’] = 3MOD9

So since future_devices returns only one object and my last if statement is not true, I should get [], right?

Answer

$(...) is returning the jQuery collection and always will regardless. So an assignment statement using .each() is the wrong approach.

Solution: Assign the return of .filter() instead. Filter is designed to accomplish your goal. Reference

NOTE: You should realize that if there is more than one match, it will return the entire collection of matches. In the code below I show only the first match, but since there are two matches (for demonstration), you’ll see that both matches are returned.

const future_devices = $('.hardware .future-hardware');
const data = {new_host: {work_order: 333}};

const future_device = $(future_devices)
  .filter(function(idx, el) {
    let device_work_order = $(el).data('work-order');
    if (device_work_order == data['new_host']['work_order']) {
      return true;
    } else {
      return false;
    }

  })
console.log("First match only: ", future_device[0]); // First match
console.log("Collection: ",future_device); // All matches
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hardware">
  <div class="future-hardware" data-work-order="111">111</div>
</div>
<div class="hardware">
  <div class="future-hardware" data-work-order="333">First Match</div>
</div>
<div class="hardware">
  <div class="future-hardware" data-work-order="111">111</div>
</div>
<div class="hardware">
  <div class="future-hardware" data-work-order="333">Second Match</div>
</div>
<div class="hardware">
  <div class="future-hardware" data-work-order="111">111</div>
</div>
<div class="hardware">
  <div class="future-hardware" data-work-order="111">111</div>
</div>


Source: stackoverflow