0

I would like to change the following method within this class:

public class ApexCalloutsDemo {

    public static HttpResponse makeCallout() {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://api.androidhive.info/contacts/');
        request.setMethod('GET');
        HttpResponse response = http.send(request);

        if (response.getStatusCode() == 200) {
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            List<Object> contacts = (List<Object>) results.get('contacts');
            System.debug('Received the following contacts:');
            for (Object contact: contacts) {
                System.debug(contact);
            }
        }
        return response;
    }

}

Into a method that returns a list of Contacts:

public static List <Contact> getContact () {
list <Contact> contacts = new list <Contacts>();

...http request here

return contacts;
}

How am I doing this? I want to display the Contacts in the component as the view part of the mvc model. Therefore I need to return a list of contacts, not the http response and not a list of objects. When I do the following I get the error "Incompatible types since an instance of Contact is never an instance of List".

public class ContactsAndWebServiceController {

    //@AuraEnabled
    /**public static List <Contact> fetchContacts() {
        List<Contact> contList = [SELECT Id, Name, Phone, Email, MailingCity from Contact LIMIT 10];
        return contList;
    }**/

    @AuraEnabled
    public static List <Contact> fetchContacts() {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://api.androidhive.info/contacts/');
        request.setMethod('GET');
        HttpResponse response = http.send(request);

        List<Contact> contactsList = new list <Contact>();

        // If the request is successful, parse the JSON response.
        if (response.getStatusCode() == 200) {
            // Deserializes the JSON string into collections of primitive data types.
            Map<String, Contact> results = (Map<String, Contact>) JSON.deserializeUntyped(response.getBody());
            // Cast the values in the 'contacts' key as a list
            List<Contact> contacts = (List<Contact>) results.get('contacts');
            System.debug('Received the following contacts:');
            for (Contact contact: contacts) {
                contactsList.add(contact);
            }
        }
        return contactsList;
    }  
}

The JSON is the endpoint of a Salesforce community example. Here is an exzerpt:

{ "contacts": [ { "id": "c200", "name": "Ravi Tamada", "email": "ravi@gmail.com", "address": "xx-xx-xxxx,x - street, x - country", "gender" : "male", "phone": { "mobile": "+91 0000000000", "home": "00 000000", "office": "00 000000" } },

10
  • 2
    good questions on SFSE should have 3 components: what are you trying to achieve, what you have tried so far and what problem do you face. First two components you provided, what about the third one? – Oleksandr Berehovskyi Apr 18 '19 at 13:05
  • What is the actual JSON content? Is it deserializable to a Contact instance or no? – David Reed Apr 18 '19 at 13:05
  • Can you clarify your question a bit? You want to change the return type of your current method from HttpResponse to List<Contacts>? If yes, that will be simply to return the contacts you already have, are you not able to do so? What issue you are facing? – Jayant Das Apr 18 '19 at 13:05
  • I want to display the Contacts in the component as the view part of the mvc model. Therefore I need to return a list of contacts, not the http response and not a list of objects. – Andrea Voggenreiter Apr 18 '19 at 13:16
  • It should be a simple transformation but it did not work for me as I am unexperienced with this topic... – Andrea Voggenreiter Apr 18 '19 at 13:17
1

The JSON you are receiving doesn't represent Salesforce Contacts as such, just data about contacts. Because the data is structured in a way that doesn't map 1:1 to the Salesforce data model, you will have to actually write code to convert the data into Contact records. For example, you would need to, for each incoming record,

  • Split the name property into a FirstName and LastName (at least).
  • Split the address property into the components of an Address compound field.
  • Extract the three phone numbers from their sub-object and map them to appropriate Contact fields.

It's not particularly complex code, but it's not trivial either and you need to think through how exactly you want to handle incoming data - especially if it is formatted badly.

However, you mentioned in the comments

I want to display the Contacts in the component as the view part of the mvc model. Therefore I need to return a list of contacts, not the http response and not a list of objects

This is not strictly accurate. You can display, in both Visualforce and Lightning, data that is not structured as sObjects or queried from the database. You won't be able to persist those records to the database without building actual sObjects out of them, but using techniques like wrapper classes that represent data in Apex structures for display and user interaction is very common. That would be a "list of objects", either a List<SomeCustomObject> or perhaps a List<Map<String, Object>>.

If you search SFSE for "wrapper class", you'll find lots of examples. (I also previously wrote about this approach in a blog post).

1
  • Hi David, it happens now that I need to process the data, like split name and address, and extract the three phone numbers from their sub-object. Could you please help me here how I do this? Do i manipulate the JSON string, because it seems I cannot do a get(property) on the object as it is not an sObject... – Andrea Voggenreiter Apr 30 '19 at 14:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.