Thursday, February 26, 2015

[Salesforce / RemoteAction] Using Date fields on a RemoteAction (PITA ALERT!)

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!

Tuesday, February 24, 2015

[NodeJS] My Simple Static Webserver


When developing pure HTML5 mockups I usually don't want to install a webserver or host my static pages on a remote webserver...
More over I sometimes like to create my own tools even if they are already on the net or they are super duper simple.

That's why I created a simple NodeJS static webserver.

You can find that simple app in this Github repo.

To use it just type:

$ git clone https://github.com/enreeco/simple-static-web-server

$ node server

This will create a local webserver @ http://localhost:3000/index.html: all the files must be kept on the root folder.

If you want to specify another port simply type:

$ node server 1234

And the magic will be @ http://localhost:1234/index.html.

Before leaving remember my motto:

Friday, February 13, 2015

[Salesforce / Mobile SDK] Salesforce Mobile SDK 3.1 brings unified app architecture

I left mobile development in the far 2010, when Salesforce development became my actual job.
In the past 6 years I've gradually switched to web dev techs over native development, and this a kind of hurted my feelings, but it was a necessary path (I merged the passion for discovering new techs with learning something usefull for my "giving-money" job).

Few months ago I made up with my team a quick demo for a client using PhoneGap and the Salesforce Mobile SDK: it was really amazing, we created a fully working app (I'm not the wizard of UIs, but it was pretty amazing) in a couple of weeks.

With the new release of the Mobile SDK we have a unique set of interfaces shared between all platforms to link your app, so you don't have to think to which feature you can use and which not, and dedicate your time to develop your awesome app in your preferred platform.


Here it is a link to the Mobile SDK Release Notes.

SmartSync for native and hybrid development is (in my opinion) the coolest utility feature in this release: this grants a common set of complete API to talk to the SmartSync layer, to ptimize data access when storing objects or doing cached queries.

This allow you to develop responsive and high qualities apps that work perfectly is an offline mode as well as online mode, creating a caching layer and a conflict resolution control.

The following is a cool mini-tutorial on how to detect conflicts when managing offline data while the details of the SmartSync usage.

For a complete example jump on this tutorial.

Other important features includes:
  • CocoaPods for iOS: iOS devs can now use CocoaPods to handle the Salesforce Mobile SDK
  • Gradle for Native Android Apps: Gradle is now supported for Android development, and will be available for Cordova Hybrid Dev in the next Cordova release
  • Certificate Based Authentication Pilot: no need for username/password request for your users to log in

This framework is getting new features release after release, and if you haven't join our developer community and start build awesome apps!