Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

92
Views
Process multiple request queries

I have an API that serves JSON data. Currently if you do api/weapons for example it gives you all the weapons available, api/weapons/weaponName gives information about that specific weapon. What I want to do is be able to api/weapons?type=sword&rarity=5 for example. I managed to pull of api/weapons?type=sword and api/weapons?rarity=5 on their own but not together.

Here's what I'm currently doing:

  let filtered = [];
  if (query.type) {
    filtered = filtered.concat((await weapons).filter(w => formatName(w.weaponType) === formatName(query.type)));
  }
  if (query.rarity) {
    filtered = filtered.concat((await weapons).filter(w => w.rarity == query.rarity));
  }
  if (!filtered.length) filtered = [await weapons]
  res.status(HttpStatusCodes.ACCEPTED).send(filtered);

formatName is just a function that makes the string all lowercase and trims it and removes all spaces.

If we take api/weapons?type=sword&rarity=5 I think what's happening right now is:

  1. It is getting all the weapons with the type "sword"
  2. It is getting all the weapons with the rarity "5"
  3. It is joining all the results together, so all the weapons with the type sword (regardless of rarity) and al the weapons with the rarity 5 (regardless of type).

I want it to filter weapons with ONLY that rarity AND ONLY that type. So only 5 rarity swords for example. What is the most beneficial way of handling this

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

I'd suggest retrieving "weapons" once and then running any filters on them without concatenating the results:

let filtered = [ ...(await weapons) ];

if (query.type) {
  filtered = filtered.filter(w => w => formatName(w.weaponType) === formatName(query.type));
}

if (query.rarity) {
  filtered = filtered.filter(w => w.rarity == query.rarity);
}

res.status(HttpStatusCodes.ACCEPTED).send(filtered);
about 4 years ago · Juan Pablo Isaza Report

0

Your current logic is testing whether one constraint OR another matches, what you actually need to do is to do an AND, which means you must perform the test in a single pass of filter.

I would slightly modify your code so that you compare all constraints that you're sending...you could further modify the logic below to accept a logical operator to test whether the rarity is >= or <= to a certain number for example.

const weapons = [{
    type: 'sword',
    name: 'swift blade of zek',
    rarity: 5
  },
  {
    type: 'mace',
    name: 'hammer of kromzek kings',
    rarity: 1
  },
  {
    type: 'sword',
    name: 'split blade of thunder',
    rarity: 2
  },
  {
    type: 'sword',
    name: 'blade of carnage',
    rarity: 5
  },
]

const getWeapons = (query = {}) => {
  let filtered = [];
  let constraints = [];

  // We could build this object dynamically but I just wanted
  // to demonstrate it using your current approach
  if (query.hasOwnProperty('type')) {
    constraints.push({
      name: 'type',
      value: query.type
    })
  }

  if (query.hasOwnProperty('rarity')) {
    constraints.push({
      name: 'rarity',
      value: query.rarity
    })
  }

  // Compare all of the conditions and only return weapons
  // that match all of the conditions passed.
  filtered = weapons.filter(w => {
    let matches = 0
    constraints.forEach(c => {
      if (w[c.name] === c.value) {
        matches += 1
      }
    })
    // ensures we only return complete matches
    return matches === constraints.length
  });

  return filtered
}

console.log(getWeapons({
  type: 'sword',
  rarity: 5
}))

about 4 years ago · Juan Pablo Isaza Report

0

Create an object which has the same property keys as the filters you want to use. Assign a function to each property where the evaluation for that specific filter is specified.

const filters = {
  type: (weapon, type) => formatName(weapon.weaponType) === formatName(type),
  rarity: (weapon, rarity) => weapon.rarity === rarity,
};

Then loop over the weapons with filter. Inside the filter loop, loop over the keys of the query variable with the every method. This method will return true or false based on if every evaluation is true or not.

In the every loop, use the keys of the query to select the filter from the filters list. Pass the weapon and the values of the query object to these filter functions and return result.

By doing this you can use one, two or no filters at all. And any new filters can be added in the filters object.

const filteredWeapons = weapons.filter((weapon) =>
  Object.keys(query).every((filterKey) => {
    if (!(filterKey in filters)) {
      return false;
    }

    const filter = filters[filterKey]
    const value = query[filterKey]
    return filter(weapon, value);
  })
);

res.status(HttpStatusCodes.ACCEPTED).send(filteredWeapons);
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!