SANA
SANA

Reputation: 689

only first Filter works when applying multiple filter on a JSON array

enter image description here I am listning to user inputs for a filter value and storing them in to an array. filters = [] my json data is to be filtered based on the values of the filters array.*But the filters can sometimes be empty if users haven't piked certain filters.

filters = ["9999", "91", "2", "5920"]
array = [
        {carID: 38871, carNumber: 5918, dispatchStatus: 2, dataVersionNr: "AAAAAAhqD2Y=", postingID: 91,peratingCompanyID:2180
        },{carID: 38872, carNumber: 5919, dispatchStatus: 2, dataVersionNr: "AAAAAAhqD2Y=", postingID: 81,peratingCompanyID:9999
        },{carID: 38873, carNumber: 5920, dispatchStatus: 2, dataVersionNr: "AAAAAAhqD2Y=", postingID: 91,peratingCompanyID:9999
        }]

I want to check if there are values in the filters and then apply all the filters to the json with this code that I got from the link below

var filtered = array.filter(o => {
    if (filters[0] && o.peratingCompanyID== filters[0]) {
      console.log(filters);
      return true;
    }
    if (filters[1] && o.postingID == filters[1]) {
      return false;
    }
    if (filters[2] && o.dispatchStatus== filters[2]) {
      return false;
    }
    if (filters[3] && o.carNumber == filters[3]) {
      return false;
    }
    return true;
  });

I want to return the json who satisfies the above filter which is

[{carID: 38873, carNumber: 5920, dispatchStatus: 2, dataVersionNr: "AAAAAAhqD2Y=", postingID: 91,peratingCompanyID:9999}]

What am I missing here?

link: Search for multiple filters in JSON using Javascript forEach and indexOf

Second example used

Upvotes: 0

Views: 363

Answers (2)

SANA
SANA

Reputation: 689

I have managed solving this using promise as below

var filters = {
  operatingCompanyID: "",
  postingID: "",
  carNumber: "",
  carAndDriverAttributes: ""
};

the array to be filtered being the var array

 function getposting() {
    var resultposting;
    if (filters.postingID) {
      resultposting = array.filter(function(o) {
        return o.postingID === filters.postingID;
      });
    } else {
      resultposting = array;
    }

    return new Promise(function(res, rej) {
      res(resultposting);
    });
  }

  getposting()
.then(function(result) {
  var resultOcId;
  if (filters.operatingCompanyID) {
    resultOcId = result.filter(function(o) {
      return o.operatingCompanyID === filters.operatingCompanyID;
    });
  } else {
    resultOcId = result;
  }

  return resultOcId;
})
.then(function(result) {
  var resultCarNum;
  if (filters.carNumber) {
    resultCarNum = result.filter(function(o) {
      return o.carNumber === filters.carNumber;
    });
  } else {
    resultCarNum = result;
  }

  return resultCarNum;
})
.then(function(result) {
  var resultAttribute;
  if (filters.carAndDriverAttributes) {
    resultAttribute = result.filter(function(o) {
      if (o.carAndDriverAttributes !== null) {
        return (
          // o.carAndDriverAttributes.indexOf(filters.carAndDriverAttributes) >
          // -1
          o.carAndDriverAttributes === filters.carAndDriverAttributes
        );
      }
    });
  } else {
    resultAttribute = result;
  }

  return resultAttribute;
})
.then(function(result) {
  var resultP;
  if (filters.postingID) {
    resultP = result.filter(function(o) {
      return o.postingID === filters.postingID;
    });
  } else {
    resultP = result;
  }

  return resultP;
})
.then(function(result) {
  updateStatus(result, 0, "freecars");
});
};

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386604

I suggest to use an object for filtering with the wanted keys and values with the same data type as the data in the objects for filtering.

filters = {
    operatingCompanyID: 9999,
    postingID: 91,
    dispatchStatus: 2,
    carNumber: 5920
}

The result is a new array without items which have some of the filter values.

The filtering with Array#every works like an logical AND, where all items have to match.

If only one item has to match, then you could use Array#some which works like a logical OR.

var filters = filters = { operatingCompanyID: 9999, postingID: 91, dispatchStatus: 2, carNumber: 5920 },
    array = [{ carID: 38871, carNumber: 5918, dispatchStatus: 2, dataVersionNr: "AAAAAAhqD2Y=", postingID: 91, operatingCompanyID: 2180 }, { carID: 38872, carNumber: 5919, dispatchStatus: 2, dataVersionNr: "AAAAAAhqD2Y=", postingID: 81, operatingCompanyID: 9999 }, { carID: 38873, carNumber: 5920, dispatchStatus: 2, dataVersionNr: "AAAAAAhqD2Y=", postingID: 91, operatingCompanyID: 9999 }],
    filtered = array.filter(o => Object
        .entries(filters)
        .every(([key, value]) => o[key] === value)
    );

console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 2

Related Questions