Stephan Boner
Stephan Boner

Reputation: 753

Parse or query with Array

I'm trying to create an or query from an array of queries. I need to use an array because the amount of queries isn't fixed, it depends on a user input.

This is some sample code from parse.com to implement an or query.

var lotsOfWins = new Parse.Query("Player");
lotsOfWins.greaterThan("wins", 150);

var fewWins = new Parse.Query("Player");
fewWins.lessThan("wins", 5);

var mainQuery = Parse.Query.or(lotsOfWins, fewWins);
mainQuery.find()
  .then(function(results) {
    // results contains a list of players that either have won a lot of games or won only a few games.
  })
  .catch(function(error) {
    // There was an error.
  });

What I'm trying to do is

var orQueries = [];

Filling the array within a for-loop with Parse.Query Objects. Then I'm calling

var userQuery = new Parse.Query.or(orQueries);

which causes a internal server error:

"TypeError: A ParseQuery must be constructed with a ParseObject or class name.

How can I solve this issue and initialize the query with an array?

Upvotes: 2

Views: 1756

Answers (2)

danh
danh

Reputation: 62686

One answer is to use JS to apply the arguments like this...

// In older JS:
var orQueries = [lotsOfWins, fewWins];
var querySum = Parse.Query.or.apply(null, orQueries);

// >=ES6:
var orQueries = [lotsOfWins, fewWins];
var querySum = Parse.Query.or(...orQueries);

I don't know the upper limit for the length of the query array, but you should take care not to put that fully under user control.

EDIT - If the queries are few in number and produce reasonably small results sets (like under 1k total?) you could forgo Query.or and do the "or" work yourself...

const _ = require('underscore');

function disjunctiveQuery(queries) {
    return Promise.all(queries).then(results => _.uniq(_.flatten(results), 'id'));
}

disjunctiveQuery([queryA, queryB, queryC, queryD]).then( ...

Upvotes: 4

Jake T.
Jake T.

Reputation: 4378

If @danh's answer doesn't work, one workaround you can do is to use Parse.Promise.when().

This takes in an array of promises, and returns the results of every promise, once every promise has completed. For queries, that means you'll end up with an array of arrays, and you'll have to discern what is what yourself (perhaps have a separate array of query identifiers to keep track?)

var promises = [];

if( needToPerformQuery0 ) {
    var query0 = new Parse.Query("MyClass");
    // Set up query
    var promise = query0.find();
    promises.push(promise);
}

if( needToPerformQuery1 ) {
    var query1 = new Parse.Query("MyClass");
    // Set up query
    var promise = query1.find();
    promises.push(promise);
}

return Parse.Promise.when(promises).then(
    function( results ) {
        if( success.count > 0 ) {
             result0 = results[0];
             //Do something
        }
    },
    function( errors ) {
        console.log("There was at least one error: " + JSON.stringify(errors));
    }
);

Upvotes: 1

Related Questions