11

I posted this to Twitter a couple of times but I'm still stumped.

I have an Apex class called "TestRemoteActionClass" with a method marked as a @RemoteAction that looks something like this:

@RemoteAction
public static List<sObject> insertRecords(List<sObject> records) {
    insert records;
    return records;
}

In my Visualforce page, I call it like this:

Visualforce.remoting.Manager.invokeAction(
    'TestRemoteActionClass.insertRecords',
    records,
    function(result, event) {
        console.log(result);
        console.log(event);
    }
);

Every time I try this, I get the following error back:

"Please provide an id or sobjectType value"

I understand the issue is related to the RemoteAction method taking a List as parameters, so it would make sense that the method needs some context to describe the SObjectType of the incoming list of records. If I change the "insertRecords" methods to take a concrete SObjectType (Account, Contact, etc), then it works fine.

However, I cannot figure out how to pass an "sobjectType" value with the parameters. I have tried the following as the "records" parameter with the same error:

[{"attributes":{"type":"Account"},"Name":"foo"}]
[{"attributes":{"sobjectType":"Account"}, "Name":"foo"}]
[{"sobjectType":"Account","Name":"foo"}]

In addition, I have tried numerous permutations of uppercase vs. lowercase combos for the 'sobjectType' parameter name. Still no luck.

Can anyone help? This issue is keeping me from creating a List "insert" call via RemoteActions, which would be huge to streamline things.

If this approach is just not possible, please let me know that too!

5 Answers 5

8

Looks like this may be a bug that will be fixed soon.

http://boards.developerforce.com/t5/Visualforce-Development/SObject-JS-Remoting-Error-Please-provide-an-id-or-sobjectType/m-p/565745#M60287

2
  • 2
    This is fixed now. Just set a property on the object called sObjectType.
    – TehNrd
    Commented Feb 25, 2013 at 1:03
  • this still seems to be broken. How do you set the property 'sObjectType' to get it to work?
    – hamayoun
    Commented Jan 16, 2017 at 0:04
2

You can also have JavaScript Remoting send you a list to work with, and then send the list back. Like:

@RemoteAction
static public List<Contact> pullCurrentContacts() {
     List<Contact> contacts = [SELECT Id, LastName, Account.Name from Contact WHERE Account.Name != ''];
     return contacts;   
}

@RemoteAction
static public Boolean updateContacts(List<Contact> contacts) {
        update contacts;
        return true;
}   
1
  • Good point and works perfect for updates. In our case, we're creating new records in JS then trying to insert - just can't figure out how to declare a type on the new record instead of relying on the remoteaction's parameter type definition.
    – tompatros
    Commented Aug 17, 2012 at 16:52
1

According to the VF Developer Guide, you can insert generic sObjects via RemoteAction calls:

Declaring a Remote Method In your controller, your Apex method declaration is preceded with the @RemoteAction annotation like this:

@RemoteAction global static String getItemId(String objectName) { ... }

Your method can take Apex primitives, collections, typed and generic sObjects, and user-defined Apex classes and interfaces as arguments. Generic sObjects must have an ID or sobjectType value to identify actual type. Interface parameters must have an apexType to identify actual type.

Unfortunately, it does not provide an example.

However, it may be worth breaking the method up into separate methods for each typed sObject and going that route if you can't get the generic sObject to work.

2
  • 1
    Separate methods is the fallback, but hoping to get a little framework going around generic insert / update / delete remoteaction calls. Update works great generically because the SFID is included. It's just the insert that's stuck.
    – tompatros
    Commented Aug 17, 2012 at 16:47
  • Another question I have for you is: Can you construct the typed sobjects outside of JSON / javascript before invoking the remoteaction call? Meaning, can you construct them on the server instead of the client? Commented Aug 17, 2012 at 16:51
0

Have you tried using this format:

[
    {
        "id": "003xxxxxxx", //Not needed in your example but put here for reference
        "type": "Contact",
        "fields": {
             "Name": "Bob"
        }
    }
]
2
  • Just gave this a try but no luck. Good idea, that looks like the format we pass in the PHP Toolkit, so it was worth a try.
    – tompatros
    Commented Aug 17, 2012 at 16:45
  • Forgot to mention, I tried swapping "type" for "sobjectType", but that also didn't work.
    – tompatros
    Commented Aug 17, 2012 at 16:45
-1

Instead of List< Sobject> as parameter change it to List< String> And Use deserialize() method.

List< Account> obj = (List< Account>) Json.deserialize(a, List< Account>.class)

Try This:

< apex:page showHeader="true" sidebar="true" controller="RemotingSObject">
    < input value="Click Me" onclick="doRemote();" type="button"/>

    < script type="text/javascript">

    function doRemote(){
        var obj = '[{"attributes":{"type":"Account"},"Name":"Acc1"},{"attributes":{"type":"Account"},"Name":"Acc2"}]';

            //You can see there is a value of sbojectType set
        console.log(obj);
       Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.RemotingSObject.receiveSObject}',
                 obj, function(result, event){
                            console.log(event);
                    console.log(result);
                   });
              }

       < /script>
< /apex:page>

Class:

public with sharing class RemotingSObject {

   @RemoteAction
   public static void receiveSObject(String param) {
     List< Account> obj = (List< Account>) Json.deserialize(param, List< Account>.class)
     system.debug(obj); 
   }
}

You must log in to answer this question.

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