8

I'm having trouble sending Date values from the client with remoted methods. If my RemoteAction method takes a plain Date value, everything works fine with the suggestion of using "toUTCString" which I found here. Unfortunately this technique does not appear to work for Date values that are parts of SObjects (either specific ones such as Contact or the anonymous "SObject" type).

Test case controller:

public with sharing class DateRemotingTest {
@RemoteAction
public static void acceptDate(Date d) {
    System.debug('got date:' + String.valueOf(d));  // works
}

@RemoteAction
public static void acceptContact(Contact c) {
    insert c;                                       // fails
    System.debug('got Contact with date:' + String.valueOf(c.BirthDate));
    delete c;
}
}

Test case page:

<apex:page controller="DateRemotingTest">
<script>
DateRemotingTest.acceptDate((new Date()).toUTCString(),
                            function(result, event) {
                                if (event.status) {
                                    console.log('plain date worked');
                                } else {
                                    console.log('plain date had some kind of error: ' + event.message);
                                }});
DateRemotingTest.acceptContact({LastName: 'Xi',
                                FirstName: 'JinPing',
                                Birthdate: (new Date(1953,5,1)).toUTCString()
                                },
                                function(result, event) {
                                    if (event.status) {
                                        console.log('plain date worked');
                                    } else {
                                        console.log('plain date had some kind of error: ' + event.message);
                                    }
                                });

</script>
</apex:page>

Loading the page results in the error

Insert failed. First exception on row 0; first error: INVALID_TYPE_ON_FIELD_IN_RECORD, Birthdate: value not of required type: Mon, 01 Jun 1953 07:00:00 GMT

I have tried numerous variations on the format, but the server isn't happy with any of them. What is the correct way of doing this?

Edit: I've created a much fancier test case - almost a console for experimenting with Date serialization style. controller and page.

2
  • To UTCString potentially converts the Date to a string. Whereas your remote method expects a date. Try changing your method argument to string in the controller. Then in your controller method you can convert to Date using one of the Date methods - valueOf or parse Commented Nov 17, 2012 at 19:03
  • That certainly is a workaround... one which I've used, in fact. But the documentation suggests you should be able to use an SObject with a Date field as-is. With your suggestion, I would have to abandon the idea of using an SObject as a parameter if it contained a Date field.
    – Jeff Trull
    Commented Nov 17, 2012 at 19:07

2 Answers 2

5

UPDATE: 9th Feb 2013. This issue has now been fixed by Salesforce from Spring'13


Yes this looks like a bug to me, I would raise a case with Salesforce with your repo code. The deserializer is placing invalid values into the SObject fields. If you comment out the insert and delete DML operations and just leave String.valueOf(contact.BirthDate) you get a nice Java internal error, 'java.lang.String cannot be converted to java.util.Date' :)

Workaround:

Based on the bug manifesting around serialising / deserialising SObject Date fields, I created a wrapped Apex class that used Apex Properties to created an Apex Date accessor to the underlying SObject Date field. Like so...

@RemoteAction
public static String acceptContact(WrappedContact wc) {
    insert wc.contact;
    delete wc.contact;
    return 'got Contact with date:' + String.valueOf(wc.contact.BirthDate);
}

public class WrappedContact
{
    public Contact contact;
    public Date birthDate { get { return contact.BirthDate; } set { contact.Birthdate = value; } }
}

This is the JavaScript code...

DateRemotingTest.acceptContact(
     {
        BirthDate: new Date(1953,5,1).toUTCString(),
        Contact: 
        {
           LastName: 'Xi',
           FirstName: 'JinPing'
        }
     },
     function(result, event) 
        {
            if (event.status) {
                console.log('plain date worked ' + result);
            } else {
                console.log('plain date had some kind of error: ' + event.message);
            }
        }
);

The emits to the browser console...

plain date worked1353196800000

plain date worked got Contact with date:1953-05-31

UPDATE:

Well the JSON serializer in Apex works just fine, which I would have expected to share the same underlying code TBH.

String cjson = '{"attributes":{"type":"Contact"},"Birthdate":"2012-11-18"}';
Contact newc = (Contact) JSON.deserialize(cjson, Contact.class);
System.debug('Date is ' + newc.BirthDate);

With this knowledge you could consider passing a JSON string parameter via JavaScript Remoting and using this JSON.deserialize manually. I can put together a sample for that if nothing else turns up. Agree its very frustrating! :-(

7
  • This is a nice workaround. Thanks so much. (not marking answered just yet in the hopes that someone has a client-side hack)
    – Jeff Trull
    Commented Nov 18, 2012 at 1:14
  • 1
    Yeah it is frustrating, I had a further thought, and updated my answer. Another workaround technically, but closer to retaining the ability to pass an entire SObject. Have you raised this with Saleforce Support in the meantime? There is also one final thing I will try for you, and that is look to see if we need to be passing some SObject type info in the JSON (much like the Apex JSON serializer needs). Commented Nov 18, 2012 at 23:42
  • Thanks again Andrew; it looks like this has been filed as support case 08471144 if you have access to that. I've also built a much fancier test case - see my edit.
    – Jeff Trull
    Commented Dec 10, 2012 at 1:47
  • Your very welcome, nice job on the support case and repo code, thanks for the follow up. Commented Dec 10, 2012 at 8:21
  • 1
    My sources inform me this is fixed in Spring 13, "in sandboxes now" if anyone cares to give it a try.
    – Jeff Trull
    Commented Jan 16, 2013 at 23:53
-1

check out the internal sforce.connection method

function getCurrentSalesForceTime(){
    var currentDateTime = sforce.connection.getServerTimestamp();
    currentDateTime = setStringToDateTime(currentDateTime.timestamp);

    return currentDateTime;
}

Also refer to this blog on the topic.

1
  • The problem I'm trying to solve is how to format a Date field of an SObject so it is acceptable to the server in a Remoting call. Your answer deals with how to convert between date strings and Javascript dates, which is a different matter.
    – Jeff Trull
    Commented Nov 17, 2012 at 19:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .