[SalesForce] ORs and ANDs in the retrieve function of Visualforce Remote Objects

Related: OR/AND condition for complex criteria with remote objects

Background

The retrieve query format allows the use of or and and clauses to create complex queries. The relevant documentation is at the end of this post.

But, JS maps only allows one value per key.

Question

How do I specify an or of one field's value? For instance, how do I build a query for an account where (BillingState is any of (Hawaii, Alaska, or California)) and (Name is like % Assoc%)?

The obvious answer (below) does not work, because JS engines will simply use the last value for BillingState ({ eq: 'California'}):

where: {
  or: {
    BillingState: { eq: 'Hawaii' },
    BillingState: { eq: 'Alaska' },
    BillingState: { eq: 'California' }
  }, 
  Name: { like: '% Assoc%' }
}

Official Documentation

Also see salesforce docs.

where conditions enable you to filter the results of a retrieve operation, much the same way that a WHERE condition in a SOQL query does. The operators that are available for where conditions are:

eq: equals
ne: not equals
lt: less than
lte: less than or equals
gt: greater than
gte: greater than or equals
like: string matching. As with SOQL, use “%” as a wildcard character.
and: logical AND, used for combining conditions
or—logical OR, used for combining conditions

Within the where object, add field name and condition pairs to create complex criteria. Multiple conditions by default are treated as AND conditions. You can use and and or to create other criteria conditions. For example:

{
  where: {
    or: {
      FirstName: { like: "M%" },
      Phone: { like: '(415)%' }
    }
  }
}

Best Answer

OPTION 1: Nested logical constructions to prevent the clash of identifiers

where: {
  or: {
    BillingState: { eq: 'Hawaii' },
    or: {
      BillingState: { eq: 'Alaska' },
      or: {...},
    },    
  }, 
  Name: { like: '% Assoc%' }
}

Caution: it seems to be important, that all ors and ands have at least two nodes. So if necessary, you have to add fake-conditions which evaluate neutrally to your needs.


OPTION 2: Add the Model fields twice (not verified)

<apex:remoteObjects jsNamespace="RemoteObjectModel">
   <apex:remoteObjectModel name="Account" >
      <apex:remoteObjectField name="BillingState" jsShorthand="State1"/>
      <apex:remoteObjectField name="BillingState" jsShorthand="State2"/>
   </apex:remoteObjectModel>
</apex:remoteObjects>
Related Topic