6

I'm passing a Javascript object through JS Remoting to update an Account record. However, if I update the NumberOfEmployees field, I'm getting the following INVALID_TYPE_ON_FIELD_IN_RECORD Employees: value not of required type: 1: [NumberOfEmployees]

String-type fields seem to work just fine. Is there something I'm missing about Integers?

The Apex:

@RemoteAction
    public static void putAccount(Account a){
        update a;
    }

The javascript:

function Account(){
    this.Id = null;
}
function putAccount(){
    var acct = new Account();
    acct.Id = document.getElementById("accountPutId").value;
    acct.NumberOfEmployees = parseInt(document.getElementById("accountPutNumEmp").value);
    console.log(acct);
    AccountRemote.putAccount(acct, function(result, event){
        console.log(event);
    });
    document.getElementById("accountPutId").value = "";
    document.getElementById("accountPutName").value = "";
}

The JSON object logged to console just before the Remoting call:

Account {Id: "001o000000BbbzbAAB", NumberOfEmployees: 1} 

Account.Name works with this just fine. Am I missing something obvious?

1
  • UPDATE: This has been accepted as a bug by R&D. I don't typically follow bugs closely, but if I hear of news of its resolution, I will try to feed this back.
    – pchittum
    Nov 6, 2014 at 11:39

4 Answers 4

3

After quite a bit of testing, this does seem like a bug to me. I wasn't able to make this work, and did quite a bit of fiddling with data types, setting input type on the input tag to number, etc.

I found a workaround, using a wrapper class to accept the payload for the remote action call, then copying that into an account object in the Apex code. This requires a bit more effort and code, but it seems to work.

My example is also making use of a second field AnnualRevenue which I was using in comparison to NumberOfEmployees just for testing purposes.

Visualforce Page

<script>
function putAccountWithWrapper(){

    var acct = {};
    acct.RecId = document.getElementById("accountPutId").value;
    acct.Employees = document.getElementById("accountPutNumEmp").value ? document.getElementById("accountPutNumEmp").value : null;
    acct.AnnualRev = document.getElementById("annRev").value ? document.getElementById("annRev").value : null;

    console.log(acct);
    RemoteApexTestNumOfEmployees.putAccountWithWrapper(acct, function(result, event){
        console.log(event);
    });
}
</script>
<div>
    <input id="accountPutId" type="text" placeholder="Id"/>
    <input id="accountPutNumEmp" type="number" placeholder="Num Of Employees"/>
    <input id="annRev" type="number" placeholder="Revenue"/>
    <button onClick="putAccountWithWrapper()">
        Go Using Wrapper
    </button>
</div>

In this one, I copy Id, but the other two fields, I am explicity setting fields to null when no value is present. There are other ways to do this, perhaps, but I'll use this in the controller to make certain I'm not accidentally nulling out values that already exist.

Apex Class

public class RemoteApexTestNumOfEmployees {

    @RemoteAction
    public static void putAccountWithWrapper(Wrapper w){

        Account a = new Account();

        a.Id = w.RecId;
        if (w.Employees != null) a.NumberOfEmployees = w.Employees ;
        if (w.AnnualRev != null)a.AnnualRevenue = w.AnnualRev ;

        update a;

        System.debug('nothing');
    }

    public class Wrapper {
        public Id RecId;
        public Integer Employees; 
        public String Name;
        public Decimal AnnualRev;
    }
}

Here again, I'm looking for nulls and not initializing the fields in the sObject when nulls are passed in so I'm not overwriting existing data.

Using the wrapper, I was finally able to get NumberOfEmployees to save.

11
  • 2
    Quite likely again with the original post being 7 years ago, @PaulN. Honestly, I really don't remember either the details, or how it was resolved. But based on it having resurfaced a year ago (based on the other answer below), and now again, my suspicion is some regression (again). There are some folks with Salesforce Support who hang out on here. Let me see if I can get their eyes on this.
    – pchittum
    Nov 18, 2021 at 10:47
  • 1
    @PaulN, I am from salesforce Support Team. We are looking into it. Nov 18, 2021 at 16:42
  • 3
    @PaulN, I was able to reproduce the issue and find the previously logged Bug(W-2419314). This would need further investigation , Are able to log a case with salesforce support and share the case number so I can take it forward. Nov 19, 2021 at 8:50
  • 1
    @PaulN, Thanks for sharing the case details. I will keep you posting the status. Nov 23, 2021 at 5:08
  • 1
    @PaulN, A known issue has been logged for the same. KI Dec 1, 2021 at 9:46
1

I ended up writing a quick solution that didn't require a wrapper:

@RemoteAction
public static void putEntity(SObject entity) {
    if (entity.getSobjectType() == Schema.Account.getSObjectType()) {
        Object temp = entity.get('NumberOfEmployees');
        if (temp != null) {
            String numberOfEmployees = (String)entity.get('NumberOfEmployees');
            try {
                entity.put('NumberOfEmployees', Integer.valueOf(numberOfEmployees));
            }
            catch (Exception e) {}
        }
    }

    update entity;
}

By pulling the NumberOfEmployees value out of the SObject and then putting it back in as an Integer Type the issue is resolved.

1
  • Note that for the String conversion, your line gave me an error... I used: String numberOfEmployees = String.valueOf( (Integer)entity.get('NumberOfEmployees') );
    – Paul N
    Nov 11, 2021 at 16:23
0

I think your problem lies in this:

function Account(){
  this.Id = null;
}
...
var acct = new Account();

This is one of those squidgey Javascript things that I kind of get, but when you invoke an object with the new operator, it does treat it differently, and somewhere deep down in the ECMA Script 5 guts, you're probably doing something that when it arrives in the Remoting API it doesn't agree with it.

I would suggest using the JS object literal notation (I've not had trouble with it anyway) for creating your account object. You don't need the Account() function anyway. It is just extra code at this point. Skip it and just do this:

function putAccount(){
  var acct = {
    "Id" : document.getElementById("accountPutId").value,
    "NumberOfEmployees" : parseInt(document.getElementById("accountPutNumEmp").value)
  };
  console.log(acct);
  AccountRemote.putAccount(acct, function(result, event){
      console.log(event);
  });
  document.getElementById("accountPutId").value = "";
  document.getElementById("accountPutName").value = "";
}
var acct = {};

Alternatively, this might work:

AccountRemote.putAccount(JSON.stringify(acct), function(result, event){
    console.log(event);
});

Regardless, I'm pretty sure the use of the 'new' operator is your problem. I put together a little test on jsbin like this:

function Account(){
  this.Id = null;
}

var acct = new Account();
acct.Id = '011240000003gwe';
acct.NumberOfEmployees = 1; 


var acct1 = {
  "Id" : '011240000003gwe',
  "NumberOfEmployees" : 1
};

console.log(acct == acct1);
//output: false

So clearly how JS looks at these two things is fundamentally different.

3
  • I tried implementing your solution with JS object literal notation and it did not change anything. Also, the JSON.stringify(acct) doesn't work as the remote function is expecting an Account, not a String. While new may cause some troubles, I do not believe it is the root cause here. Any other thoughts?
    – ricka
    Oct 30, 2014 at 22:21
  • Interestingly enough, I just tried this with a custom number field I created on account, and both my way and your way work. That means this is definitely something either with standard fields or with Account.NumberOfEmployees specifically. Maybe a bug?
    – ricka
    Oct 30, 2014 at 22:28
  • I have some time to play with this now as last night was just me shooting from the hip and not testing...let me try your code in my own org and see what comes up.
    – pchittum
    Oct 31, 2014 at 10:00
0

I know this is very late, but recently we face similar issue and raise ticket with salesforce , after spending some time with salesforce support , Finally their Account Product Team (which is primarily responsible for Account object development) accept this as defect and they resolved it.

Please check if this is working for you as well. We face this issue in our appexchange product , so validated it against all orgs ( developer , enterprise , scratch org etc)

All looks good now.

You must log in to answer this question.

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