Tuesday, February 12, 2013

Setting field values using CSOM client side - Another look

Last night after hitting publish, I enjoyed a long ride home on the metro...  I was able to catch up on some of my reading.  It's a relaxing part of my day and sometimes exciting because I get to grind away on concepts that I'm working on.  Last night did not disappoint.

spUtils - setColumnVal


As I said in the previous post, I've already tackled this problem, however, I didn't really like the implementation.  So, here's my bright idea... Toggle the library back to use setColumnVal and see what the XML looks like under the hood.  Doing just that, here's what's produced( I've snipped this for brevity ):


<Method Name="SetFieldValue" Id="26" ObjectPathId="21">
  <Parameters>
<Parameter Type="String">AssignedTo</Parameter>
<Parameter Type="Array">
<Object TypeId="{c956ab54-16bd-4c18-89d2-996f57282a6f}">
<Property Name="LookupValue" Type="String">DEV\Administrator</Property>
<Property Name="LookupId" Type="Number">-1</Property>
</Object>
<Object TypeId="{c956ab54-16bd-4c18-89d2-996f57282a6f}">
<Property Name="LookupValue" Type="String">DEV\spUser</Property>
<Property Name="LookupId" Type="Number">-1</Property>
</Object>
</Parameter>
</Method>


So based on that, it's easy to see the people picker XML has to be an array of objects.  Let's give that a shot now using this code mixed with parseAndSetFieldValue.

spUtils - parseAndSetFieldValue revisited


spUtils.updateListItems({
listName: "spUtils",
updates : {
1 : {
"Title" : spUtils.isoDate(),
"AssignedTo" : [
{
LookupValue: "DEV\\Administrator",
LookupId: -1
},
{
LookupValue: "DEV\\spUser",
LookupId: -1
}
]
}
},
success: function( data, ctx ) {
debugger;
}
});

Using the code above produces this XML ( snipped as well for brevity ):

<Method Name="ParseAndSetFieldValue" Id="44" ObjectPathId="21">
  <Parameters>
<Parameter Type="String">AssignedTo</Parameter>
<Parameter Type="Array">
<Object Type="Dictionary">
<Property Name="LookupValue" Type="String">DEV\Administrator</Property>
<Property Name="LookupId" Type="Number">-1</Property>
</Object>
<Object Type="Dictionary">
<Property Name="LookupValue" Type="String">DEV\spUser</Property>
<Property Name="LookupId" Type="Number">-1</Property>
</Object>
</Parameter>
  </Parameters>
</Method>


It's remarkably close to the XML that actually works.  The only thing that is different is the Object Type.  Sadly, this is all that it takes for this to FAIL.  Yep, that's right...  Trying to be smarter than the average bear, let's give it another shake.  This time, I'm going to take some code out of the setColumnVal method and drop it into an array.  Take a look at this:

spUtils.updateListItems({
listName: "spUtils",
updates : {
1 : {
"Title" : spUtils.isoDate(),
"AssignedTo" : [  SP.FieldUserValue.fromUser("DEV\\Administrator"),
  SP.FieldUserValue.fromUser("DEV\\spUser")
]
}
},
success: function( data, ctx ) {
debugger;
}
});


This in turn produces XML that *should* work!

<Method Name="ParseAndSetFieldValue" Id="44" ObjectPathId="21">
  <Parameters>
  <Parameter Type="String">AssignedTo</Parameter>
  <Parameter Type="Array">
  <Object TypeId="{c956ab54-16bd-4c18-89d2-996f57282a6f}">
  <Property Name="LookupValue" Type="String">DEV\Administrator</Property>
<Property Name="LookupId" Type="Number">-1</Property>
  </Object>
  <Object TypeId="{c956ab54-16bd-4c18-89d2-996f57282a6f}">
<Property Name="LookupValue" Type="String">DEV\spUser</Property>
<Property Name="LookupId" Type="Number">-1</Property>
  </Object>
  </Parameter>
  </Parameters>
</Method>


The only difference this time is the Method Name attribute.  Sadly, even this FAILS! I was going to continue with using numbers, but with this being a show stopper, I'm convinced I've researched this thoroughly enough.  This may be different in SP2013, it simply doesn't work in SP2010, therefore unreliable.

What's next?


Since I need the context of the list item to set its values when using the .update() method, it's not feasible to change what I have currently.  To set lookups and people picker values in CSOM, you have to use the code I've already written.  Guess it's time I start documenting the API, eh?

No comments: