0

I keep receiving the method does not exist error. With the below code. Here is my searchClass definition:

public class searchClass {


    public Integer item_count;
    public List<Accounts> accounts;


    public class Accounts {
        public String account_number;
        public String new_id;
        public String record_type_id;
        public String account_type;
    }

    public static searchClass parse(String json) {
        return (searchClass) System.JSON.deserialize(json, searchClass.class);
    }
}

Now I'm looking to get the attributes (from another class) from searchClass.accounts (declared as sClass below):

searchClass sClass = (searchClass)JSON.deserialize(jsonStr, searchClass.class);

Map<String, Object> fieldToValue = sClass.accounts.getPopulatedFieldsAsMap();
for (String key : fieldToValue.keySet()) {
    System.debug(key + '->' + fieldToValue.get(key));
}

My objective is to compare sClass.accounts[1].key to sClass.accounts[2].key. Or sClass.accounts.fieldtoValue[1]? I'm not sure what the syntax would even look like.

1
  • Where are you getting the method does not exist error? Commented Nov 17, 2017 at 21:42

2 Answers 2

3

Edit:

SFDCFox's answer explains why the standard method with the same name does not work in your case. Basically, getPopulatedFieldsAsMap() only works on SObject and it's derivatives. Since you're using a custom class, you need to define it for yourself.

Answer:

The answer to your question is pretty straight forward. You're calling a method that doesn't exist. The class definition for Accounts does not have a method called getPopulatedFieldsAsMap() defined for it.

You also have a list named accounts and a class named accounts. You should, even if for nothing more than code readability, change your class name to account and your list can stay accounts.

You'll need to define your method in order to use it:

public class searchClass {
    public Integer item_count;
    public List<Accounts> accounts;

    public class Account {
        public String account_number;
        public String new_id;
        public String record_type_id;
        public String account_type;
        /* Define your method here */
        public Map<String, Object> getPopulatedFieldsAsMap() {
            Map<String, Object> result = new Map<String, Object>();
            result.put('account_number', this.account_number);
            /* rinse and repeat */
            return result;
        }
    }

    public static searchClass parse(String json) {
        return (searchClass) System.JSON.deserialize(json, searchClass.class);
    }
}

Then:

SearchClass sclass = SearchClass.parse(jsonStr);

for (SearchClass.Account a : sclass.accounts) {
    Map<String, Object> fieldToValue = a.getPopulatedFieldsAsMap();

    for (String key : fieldToValue.keySet()) {
        system.debug(key + '->' + fieldToValue.get(key));
    }
}

Edit:

Also keeping in mind with what SFDCFox said regarding wanting to use a map. Lets go one more step further and assume you want to de-dupe your account list. The below will automatically build a map of unique accounts (sort of but lets not get too far away from the question here).

SearchClass sclass = SearchClass.parse(jsonStr);
Map<String, SearchClass.Account> accountMap = new Map<String, SearchClass.Account>();

for (SearchClass.Account a : sclass.accounts) {
    accountMap.put(a.Account_Number, a);
}

Final Note:

If you haven't already heard of / played with it; JSON2Apex is a pretty sweet tool.

Update:

To answer the question in the comments

If you're trying to compare two accounts you'd need something like this:

Map<String, Map<String, Object>> accountsMap = new Map<String, Map<String, Object>>();

for (SearchClass.Account a : sclass.accounts) {
    accountsMap.put(a.Account_Number, a.getPopulatedFieldsAsMap());
}

if (accountsMap.get('Account#1').get('FieldKey') == accountsMap.get('Account#2').get('FieldKey')) {
    //Do Something
}

This is just one way to do it. You could use a list instead of a map and index them using the [] operator as well but that would give you no way to know which 2 accounts you are comparing (and will result in extremely inefficient code at the very least).

Also, it seems like the big problem you're having is that you don't really understand the basic data structures and how they work. These structures are not restricted to APEX and appear in many different programming languages and the syntax is the same as most C derivatives.

The best advice I can give you is to be honest with your boss about your experience as a developer. Otherwise you're in for a very long and hard project and you can expect a lot of backlash from the stackexchange community if you keep asking questions like this one.

4
  • Thank you. Somewhere along the line I thought putting the getPopulatedFieldAsMap method within the searchClass class, not the the accounts class would allow me to get the attributes from the top down or something. Although, how would I compare key 1 to key 1 when there is two accounts using this logic? Would fieldToValue[0].get(key) return all keys for account one and would fieldToValue[0].get(key) return all keys for account two in a way that I could compare one key against the other?
    – S.B.
    Commented Nov 20, 2017 at 16:26
  • No, that won't quite work, Ill have to update the answer again.
    – gNerb
    Commented Nov 21, 2017 at 16:42
  • @S.Morrison Updated my answer
    – gNerb
    Commented Nov 21, 2017 at 17:00
  • Thank you, I appreciate the advice and apologize for my lack of knowledge (which is well known internally). You went above and beyond to answer my question, hopefully your response is of use to anyone with a similar question. I was surprised that this is so complicated. I was able to achieve this functionality with ease in javascript.
    – S.B.
    Commented Nov 21, 2017 at 18:46
3

getPopulatedFieldsAsMap only works on sObject objects, not arbitrary object types. If you wanted to compare two values, that's exactly what you'd do:

if(sClass.Accounts[1].account_number == sClass.Accounts[2].account_number) {
  ...

I think, however, you're ultimately headed down the wrong path, because what you probably want is a Map to find duplicate keys.

2
  • My intention is to look at the attributes of the first account returned, if one of those attributes are blank or null, then check to see if that same attribute in the second account returned is defined and if so, set the key of account 2 to the same key of account 1. In short, if account 1 is missing data and account 2 does, populate account 1 with account 2 data. Ideally, I'd like to cover all of my bases and have a way to compare not account only account 1 to 2, but compare every account against all other accounts.
    – S.B.
    Commented Nov 20, 2017 at 16:33
  • @S.Morrison That seems pretty crazy... I can't imagine the business need for something like that.
    – gNerb
    Commented Nov 21, 2017 at 17:02

You must log in to answer this question.

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