I’ve just come through a bug on the Date field handling for Visual Force @RemoteAction.
We want to pass to a remote action a list of SObjects to be handled correctly.
This is the controller that hosts the @RemoteAction method:
public class MyController(){ @RemoteAction public String doAction(List<contact> contacts){ return 'All is ok!'; } }
This is the JS on the VF page:
function action(){ var contact1 = {"LastName":"Smith", "FirstName":"John", "Phone" : "999-999-999"}; var contact2 = {"LastName":"Brown", "FirstName":"Mike", "Phone" : "123-456-789"}; var contactList= [contact1, contact2]; Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.MyController.doAction}', accList || [], function(result, event){ if(event.status){ alert(result); }else{ //generic event error alert(event.message); } },{escape: false, timeout: 120000}); }
This runs perfectly.
But let’s add a Date field on the JS part:
function action(){ var contact1 = {"LastName":"Smith", "FirstName":"John", "BirthDate":"1980-01-01", "Phone" : "999-999-999"}; var contact2 = {"LastName":"Brown", "FirstName":"Mike", "BirthDate":"1982-11-21", "Phone" : "123-456-789"}; var contactList= [contact1, contact2]; Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.MyController.doAction}', contactList || [], function(result, event){ if(event.status){ alert(result); }else{ //generic event error alert(event.message); } },{escape: false, timeout: 120000}); }
And all messes up, stating that you are passing an incorrect type to MyController.doAction(List).
The problem is related to how the Date type serialization is done when invoking the Remote Action (it is apparently a bug not fixed yet).
The solution is to pass a serialized version of the JS array and deserialize it with Apex:
public class MyController(){ @RemoteAction public String doAction(String serializedContacts){ List<contact> contacts = (List<contact>)JSON.deserialize(objList,List<contact>.class); return 'All is ok!'; } }
function action(){ var contact1 = {"LastName":"Smith", "FirstName":"John", "BirthDate":"1980-01-01", "Phone" : "999-999-999"}; var contact2 = {"LastName":"Brown", "FirstName":"Mike", "BirthDate":"1982-11-21", "Phone" : "123-456-789"}; var contactList= [contact1, contact2]; Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.MyController.doAction}', JSON.stringify(contactList || []), function(result, event){ if(event.status){ alert(result); }else{ //generic event error alert(event.message); } },{escape: false, timeout: 120000}); }
Remember: don’t mess with JSON serialization!
CharlesDb
It’s also possible to just send the unix millisecond timestamp and therefore not needed to start playing with the JSON serialize/deserialize
Enrico Murru
You’re right Charles! I wanted to prove the use of the right data type!