Skip to main content
Notice removed Authoritative reference needed by Mark Pond
Bounty Ended with Alex Tennant's answer chosen by Mark Pond
Updated title and question content to improve context of the problem.
Source Link
Mark Pond
  • 23.1k
  • 2
  • 60
  • 104

What is the correct way to send an Apex type containing DateTime member types in the payloadmembers to RemoteActions?

I have seen quiteUpdate: this is only an issue with a few questions and answers regarding the conversion and display ofconcrete type in a JSON serializedcustom class. I implemented the same pattern with the DateTimeContact sObject containing a DateTime field in JavaScript, no exception thrown. Code below and the effects of UTC on that data related to the user's locale but I have yet to be able to find a solutionquestion title updated to the issue I'm facing heredemonstrate this difference in behavior.

 

I am using @RemoteAction methods to expose a custom Apex Type to the page. When performing the retrieve operation, the DateTime members on the class are serialized into the unix epoch format. Like so:

This seems likeis "JS Remoting: 101" and it shocksfrustrates me that it does not work.

Update: apparently this is only an issue with a concrete type on my own class. Tried the same code with the Contact sObject, no exception thrown. Code below updated to demonstrate this properly.

What is the correct way to send DateTime member types in the payload to RemoteActions?

I have seen quite a few questions and answers regarding the conversion and display of a JSON serialized DateTime field in JavaScript and the effects of UTC on that data related to the user's locale but I have yet to be able to find a solution to the issue I'm facing here.

I am using @RemoteAction methods to expose a custom Apex Type to the page. When performing the retrieve operation, the DateTime members on the class are serialized into the unix epoch format.

This seems like "JS Remoting: 101" and it shocks me that it does not work.

Update: apparently this is only an issue with a concrete type on my own class. Tried the same code with the Contact sObject, no exception thrown. Code below updated to demonstrate this.

What is the correct way to send an Apex type containing DateTime members to RemoteActions?

Update: this is only an issue with a concrete type in a custom class. I implemented the same pattern with the Contact sObject containing a DateTime field, no exception thrown. Code below and the question title updated to demonstrate this difference in behavior.

 

I am using @RemoteAction methods to expose a custom Apex Type to the page. When performing the retrieve operation, the DateTime members on the class are serialized into the unix epoch format. Like so:

This is "JS Remoting: 101" and it frustrates me that it does not work properly.

Tweeted twitter.com/#!/StackSalesforce/status/638402363095678977
reformatted the question to better show the two details of the problem I would like answered.
Source Link
Mark Pond
  • 23.1k
  • 2
  • 60
  • 104

What is the correct way to implement this very simple pattern? Am I just doing it wrong? This seems like "JS Remoting: 101" and it shocks me that it does not work.

Update: apparently this is only an issue with a concrete type on my own class. Tried the same code with the Contact sObject, no exception thrown. apparently this is only an issue with a concrete type on my own class. Tried the same code with the Contact sObject, no exception thrown. Code below updated to demonstrate this.

Questions:

  1. What is the correct way to implement this very simple pattern?
  2. Why does this work properly with an sObject but not with an apex type?

What is the correct way to implement this very simple pattern? Am I just doing it wrong? This seems like "JS Remoting: 101" and it shocks me that it does not work.

Update: apparently this is only an issue with a concrete type on my own class. Tried the same code with the Contact sObject, no exception thrown.

This seems like "JS Remoting: 101" and it shocks me that it does not work.

Update: apparently this is only an issue with a concrete type on my own class. Tried the same code with the Contact sObject, no exception thrown. Code below updated to demonstrate this.

Questions:

  1. What is the correct way to implement this very simple pattern?
  2. Why does this work properly with an sObject but not with an apex type?
Notice added Authoritative reference needed by Mark Pond
Bounty Started worth 200 reputation by Mark Pond
Added detail about it working with an sObject.
Source Link
Mark Pond
  • 23.1k
  • 2
  • 60
  • 104

Update: apparently this is only an issue with a concrete type on my own class. Tried the same code with the Contact sObject, no exception thrown.

Controller

public with sharing class DateTimeSerializationController {
    
    public class MyItem {
        public String name      { get; set; }
        public DateTime theDate { get; set; }
    }
    
    @RemoteAction
    public static MyItem fetchTheItem() {
        MyItem item = new MyItem();
        item.name = 'Item Name';
        item.theDate = DateTime.now();
        return item;
    }
    
    @RemoteAction
    public static MyItem storeTheItem(MyItem item) {
        // DML or something similar could happen here
        system.debug(item);
        
        return item;
    }
    
    @RemoteAction
    public static Contact fetchTheContact() {
        Contact item = new Contact();
        item.FirstName = 'Joe';
        item.LastName = 'Bob';
        item.My_Date__c = DateTime.now();
        return item;
    }
    
    @RemoteAction
    public static Contact storeTheContact(Contact item) {
        // DML or something similar could happen here
        system.debug(item);
        
        return item;
    }
}
<apex:page controller="DateTimeSerializationController">
    <script>
        window.myApp = window.myApp || {};
        
        window.myApp.fetchfetchItem = function() {
        
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.fetchTheItem',
                function(result, event){
                    if (event.status) {
                        console.log(result);
                        myApp.myItem = result;    
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        
        }
        
        window.myApp.storestoreItem = function() {
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.storeTheItem',
                myApp.myItem,
                function(result, event){
                    if (event.status) {
                        console.log(result);
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        }
        
        window.myApp.fetchContact = function() {
        
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.fetchTheContact',
                function(result, event){
                    if (event.status) {
                        console.log(result);
                        myApp.myContact = result;    
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        
        }
        
        window.myApp.storeContact = function() {
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.storeTheContact',
                myApp.myContact,
                function(result, event){
                    if (event.status) {
                        console.log(result);
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        }
    </script>

    <p>Open the browser console and then click the buttons.</p> 

    <button onclick="myApp.fetchItem();">Fetch Item</button>
    <button onclick="myApp.fetchstoreItem();">Fetch<;">Store Item</button> 

    <button onclick="myApp.storefetchContact();">Store<;">Fetch Contact</button>
    <button onclick="myApp.storeContact();">Store Contact</button>
</apex:page>

Controller

public with sharing class DateTimeSerializationController {
    
    public class MyItem {
        public String name      { get; set; }
        public DateTime theDate { get; set; }
    }
    
    @RemoteAction
    public static MyItem fetchTheItem() {
        MyItem item = new MyItem();
        item.name = 'Item Name';
        item.theDate = DateTime.now();
        return item;
    }
    
    @RemoteAction
    public static MyItem storeTheItem(MyItem item) {
        // DML or something similar could happen here
        system.debug(item);
        
        return item;
    }
    
}
<apex:page controller="DateTimeSerializationController">
    <script>
        window.myApp = window.myApp || {};
        
        window.myApp.fetch = function() {
        
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.fetchTheItem',
                function(result, event){
                    if (event.status) {
                        console.log(result);
                        myApp.myItem = result;    
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        
        }
        
        window.myApp.store = function() {
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.storeTheItem',
                myApp.myItem,
                function(result, event){
                    if (event.status) {
                        console.log(result);
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        }
    </script>

    <p>Open the browser console and then click the buttons.</p>
    
    <button onclick="myApp.fetch();">Fetch</button>
    <button onclick="myApp.store();">Store</button>

</apex:page>

Update: apparently this is only an issue with a concrete type on my own class. Tried the same code with the Contact sObject, no exception thrown.

Controller

public with sharing class DateTimeSerializationController {
    
    public class MyItem {
        public String name      { get; set; }
        public DateTime theDate { get; set; }
    }
    
    @RemoteAction
    public static MyItem fetchTheItem() {
        MyItem item = new MyItem();
        item.name = 'Item Name';
        item.theDate = DateTime.now();
        return item;
    }
    
    @RemoteAction
    public static MyItem storeTheItem(MyItem item) {
        // DML or something similar could happen here
        system.debug(item);
        
        return item;
    }
    
    @RemoteAction
    public static Contact fetchTheContact() {
        Contact item = new Contact();
        item.FirstName = 'Joe';
        item.LastName = 'Bob';
        item.My_Date__c = DateTime.now();
        return item;
    }
    
    @RemoteAction
    public static Contact storeTheContact(Contact item) {
        // DML or something similar could happen here
        system.debug(item);
        
        return item;
    }
}
<apex:page controller="DateTimeSerializationController">
    <script>
        window.myApp = window.myApp || {};
        
        window.myApp.fetchItem = function() {
        
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.fetchTheItem',
                function(result, event){
                    if (event.status) {
                        console.log(result);
                        myApp.myItem = result;    
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        
        }
        
        window.myApp.storeItem = function() {
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.storeTheItem',
                myApp.myItem,
                function(result, event){
                    if (event.status) {
                        console.log(result);
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        }
        
        window.myApp.fetchContact = function() {
        
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.fetchTheContact',
                function(result, event){
                    if (event.status) {
                        console.log(result);
                        myApp.myContact = result;    
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        
        }
        
        window.myApp.storeContact = function() {
            Visualforce.remoting.Manager.invokeAction(
                'DateTimeSerializationController.storeTheContact',
                myApp.myContact,
                function(result, event){
                    if (event.status) {
                        console.log(result);
                    } else {
                        console.log(event.message);
                    }
                }, 
                {escape: true}
            );
        }
    </script>

    <p>Open the browser console and then click the buttons.</p> 

    <button onclick="myApp.fetchItem();">Fetch Item</button>
    <button onclick="myApp.storeItem();">Store Item</button> 

    <button onclick="myApp.fetchContact();">Fetch Contact</button>
    <button onclick="myApp.storeContact();">Store Contact</button>
</apex:page>
Source Link
Mark Pond
  • 23.1k
  • 2
  • 60
  • 104
Loading