Code not returning expected query

May 12, 2015 at 2:34 PM
I've used this function before with no problems, but I've edited it a bit to work on a new SharePoint 2010 site. I'm using the function createCamlQuery below to dynamically created a query using an array of values. Please consider:
    function createCamlQuery(arrayName, fieldName, onlyActive) {  
        var camlBuilder = new CamlBuilder(); 
        var camlFull = 'camlBuilder.Where().'; 
        var vendorStart = 'TextField("' + fieldName + '").EqualTo("'; 
        var vendorEnd = '").'; 
        var orOp = 'Or().'; 
        var andOp = 'And().TextField("HighRiskProtocol").Contains("Test").';
        var toString = 'ToString();'; 
        var vendorName;
        var vendorFull;
        var lastIndex = arrayName.length-1;     
        
        for (var i=0;i<lastIndex+1;i++) {
            vendorName = arrayName[i];
            vendorFull = vendorStart + vendorName + vendorEnd + orOp;
            camlFull += vendorFull; 
        }           
        

        if (onlyActive == "true") {
            vendorName = arrayName[lastIndex];
            vendorFull = vendorStart + vendorName + vendorEnd + andOp + toString;
            camlFull += vendorFull;
        }
        else {
            vendorName = arrayName[lastIndex];
            vendorFull = vendorStart + vendorName + vendorEnd + toString;
            camlFull += vendorFull;     
        }
        
        console.log(camlFull);
        var query = eval(camlFull);
        query = "<Query>" + query + "</Query>";   

        console.log(query);
        return query;  
    }   
The first console.log, prior to evaluation, returns:
camlBuilder.Where().TextField("ID").EqualTo("11").Or().TextField("ID").EqualTo("153").Or().TextField("ID").EqualTo("46").Or().TextField("ID").EqualTo("46").And().TextField("HighRiskProtocol").Contains("Test").ToString(); 
which appears to me to be correct; however, the following query is returned which is not correct:
 <Query><Where><Or><Eq><FieldRef Name="ID" /><Value Type="Text">11</Value></Eq><Or><Eq><FieldRef Name="ID" /><Value Type="Text">153</Value></Eq><Or><Eq><FieldRef Name="ID" /><Value Type="Text">46</Value></Eq><And><Eq><FieldRef Name="ID" /><Value Type="Text">46</Value></Eq><Contains><FieldRef Name="HighRiskProtocol" /><Value Type="Text">Test</Value></Contains></And></Or></Or></Or></Where></Query>
The last value of ID, 46, winds up inside the AND statement, which causes the data returned to be incorrect. I've been looking at this for a couple days and just cannot figure out what I'm doing wrong.

Any assistance is appreciated.
Coordinator
Oct 7, 2015 at 1:03 PM
Edited Oct 7, 2015 at 1:04 PM
Hi,

As far as I remember And()-s and Or()-s are evaluated in right-to-left order, so probably to fix your problem you just need to change order corresponding your logic.

This particular query can actually simplified like this:
var query = new CamlBuilder().Where().TextField("ID").In(arrayName).And().TextField("HighRiskProtocol").Contains("Test").ToString()
Also, for building more complex dynamic expressions, you can use CamlBuilder.Expression.
Example:
var expressions = [];
for (var i=0;i<arrayName.length;i++)
{
  expressions.push(CamlBuilder.Expression().Where().TextField("ID").EqualTo(arrayName[i]));
}
var query = new CamlBuilder().Where().Any(expressions).And().TextField("HighRiskProtocol").Contains("Test").ToString(); 
P.S. Terribly sorry for the very late answer, for some time codeplex had problems sending out emails, I think that's why I completely missed your question.