function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Amar GadewarAmar Gadewar 

Apex REST Callouts Challenge

In the Challenge it is requested to make a call to https://th-apex-http-callout.herokuapp.com/animals/:id.

Question is are they expecting a GET call or POST call. Most probably a GET call. But suppose integet pass to the method getAnimalNameById is "45678". How are we to formulate the URL.

Is it Option 1> replace id with value i.e https://th-apex-http-callout.herokuapp.com/animals/:45678
Option 2> pass using equal sign i.e https://th-apex-http-callout.herokuapp.com/animals/:id=45678.

Regardless i am getting the following response {"animal": {"id": 0,"name": "","eats": "","says": ""}}. I want some test data to verify the code is working does any body has that
Best Answer chosen by Amar Gadewar
Bob RobinsonBob Robinson
The actual endpoint doesn't have the colon in it.  Try:
 
request.setEndpoint("https://th-apex-http-callout.herokuapp.com/animals/" + identifier);
which for me is returning the following data (if identifier == 1):
 
{"animal":{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"}}
Still stuck on exactly how to parse that JSON, but hopefully this helps you move further.

 

All Answers

Amar GadewarAmar Gadewar
Code that i have in the Challenge which is failing is

Global class AnimalLocator {
    
     Global static String getAnimalNameById(Integer  indentifier) {
         
         String returnName ;
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/:id=' + indentifier);
        request.setMethod('GET');
       
        HttpResponse response = http.send(request);
        // Parse the JSON response
        if (response.getStatusCode() == 200) {
            JSON2AnimalApex animal = JSON2AnimalApex.parse(response.getBody());
            returnName = animal.animal.name;
        } 
        return returnName;
    }

}
Bob RobinsonBob Robinson
The actual endpoint doesn't have the colon in it.  Try:
 
request.setEndpoint("https://th-apex-http-callout.herokuapp.com/animals/" + identifier);
which for me is returning the following data (if identifier == 1):
 
{"animal":{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"}}
Still stuck on exactly how to parse that JSON, but hopefully this helps you move further.

 
This was selected as the best answer
Amar GadewarAmar Gadewar
Thanks a Bob, by making this change i am getting the result as well score the 500 points on the Challenge. For JSON parsing i am using the "JSON2Apex" link https://json2apex.herokuapp.com/ to parse the JSON and provide me with Apex Class which i am using in the above code.
Amar GadewarAmar Gadewar
public class AnimalLocator {
    
     public static String getAnimalNameById(Integer  indentifier) {
         
         String returnName ;
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/' + indentifier);
        request.setMethod('GET');
       
        HttpResponse response = http.send(request);
        // Parse the JSON response
        if (response.getStatusCode() == 200) {
            JSON2AnimalApex animal = JSON2AnimalApex.parse(response.getBody());
            returnName = animal.animal.name;
        } 
        return returnName;
    }

}
Bob RobinsonBob Robinson
Amar,

Thanks for the tip on JSON2Apex.  I did solve it a different way, in case anyone wants to try it later.  Amar's solution is better though.
 
Map<String,Object> results = (Map<String,Object>)JSON.deserializeUntyped(response.getBody());           
Map<String,Object> animal = (Map<String,Object>)results.get('animal');
String animalName = (String)animal.get('name');

 
Scott Harbaugh 7Scott Harbaugh 7
Also just a note, the only valid values for the ID are "1" or "2", everything else seems to return null.
Giri Cumbum 6Giri Cumbum 6
Hi, this challenge gives me the below error:
Challenge Not yet complete... here's what's wrong: 
Executing the 'getAnimalNameById' method on 'AnimalLocator' failed. Make sure the method exists with the name 'getAnimalNameById', is public and static, accepts an Integer and returns a String.

I defined the method as below:
public class AnimalLocator {
    public static String getAnimalNameById (Integer i)

Not sure, why i am seeing this error. can anyone help?
Febrian Tarigan 7Febrian Tarigan 7
Hi Giri,

Did you return a string at the end of your method?

You can try this one:
public class AnimalLocator {
    public static String getAnimalNameById (Integer animalId){
        String animalName;
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/'+animalId);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        // 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, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            // Cast the values in the 'animals' key as a list
			Map<String,Object> animal = (Map<String,Object>)results.get('animal');
            System.debug('Received the following animals:');
            animalName = (String)animal.get('name');
        }
        return animalName;

    }
}

 
Giri Cumbum 6Giri Cumbum 6
Yes, It has the string value returned at the end of the classand the class successfully saved.
Kiran PandiyanKiran Pandiyan
@Giri Cumbum paste your entire class , we will try to solve it
S Kumar.ax1063S Kumar.ax1063

@Febrian Tarigan 7: Thanks, it solved my problem too. The main reason is, in the challenge it is asked to pass id as the variable in endpoint URL. which is a keyword.
Prem KrishnanPrem Krishnan
Hi All,
To parse the json I creaed a class as below using json to apex and some editing.
 
public class jsontoApex {

    /*public class jsontoApex {
        public Animal animal;
    }*/
    public Animal animal;
    
    public class Animal {
        public Integer id;
        public String name;
        public String eats;
        public String says;
    }

    
    public static jsontoApex parse(String json) {
        return (jsontoApex) System.JSON.deserialize(json, jsontoApex.class);
    }
}
Then in the AnimalLocator class I used the above class to parse it as below.
public class AnimalLocator {

    //challenge from trailhead lesson Apex REST Callouts
    public static string getAnimalNameById(Integer animalid){
        Http http = new Http();
        String str = '';
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/'+animalid);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
        // If the request is successful, parse the JSON response.
        if (response.getStatusCode() == 200) {
			
			jsontoapex obj = jsontoapex.parse(response.getBody());
            System.debug('Obj: '+obj.animal.name );
            str = obj.animal.name;
        }
        return str;
    }
}

You can see that I get the value of animal name using the line
System.debug('Obj: '+obj.animal.name );
Hope this helps.


 
auxious davuluriauxious davuluri
Hallo, This is what I wrote the code and getting error like  Executing the 'getAnimalNameById' method on 'AnimalLocator' failed. Make sure the method exists with the name 'getAnimalNameById', is public and static, accepts an Integer and returns a String.
Any Help would be great, TIA.
## Animal Locator :
public class AnimalLocator {
    public static String getAnimalNameById(Integer id) {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/'+id);
        request.setMethod('GET');
        HttpResponse response = http.send(request);
           /*Map<String,Object> results = (Map<String,Object>)JSON.deserializeUntyped(response.getBody());
        system.debug('---->results'+results);
        List<Object> animals = (List<Object>) results.get('animal');
        system.debug('---->animal'+animals);*/
        Map<Integer,String> mapAnimal = new Map<Integer,String>();
        Integer varId;
        String varName;
        JSONParser parser1= JSON.createParser(response.getBody());
        while (parser1.nextToken() != null) {
            if ((parser1.getCurrentToken() == JSONToken.FIELD_NAME) && (parser1.getText() == 'id')) {
                // Get the value.
                parser1.nextToken();
                // Fetch the ids for all animals in JSON Response.
                varId=parser1.getIntegerValue();
                System.debug('---->varId-->'+varID);
                parser1.nextToken();
            }
            if ((parser1.getCurrentToken() == JSONToken.FIELD_NAME) && (parser1.getText() == 'name')) {
                parser1.nextToken();
                // Fetch the names for all animals in JSON Response.
                varName=parser1.getText();
                System.debug('---->varName-->'+varName);
            }
            mapAnimal.put(varId,varName);
        }
        system.debug('---->mapAnimal-->'+mapAnimal);
        return mapAnimal.get(id); 
        
    }
}
## Mock Test :
@isTest
global class AnimalLocatorMock implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest request) {
        // Create a fake response
        HttpResponse response = new HttpResponse();
        response.setHeader('Content-Type', 'application/json');
        response.setBody('{"animal":[{"id":1,"name":"chicken","eats":"chicken food","says":"cluck cluck"},{"id":2,"name":"duck","eats":"worms","says":"pek pek"}]}');
        response.setStatusCode(200);
        return response; 
    }
}

## Test Class :
@isTest
private class AnimalLocatorTest {
@isTest static void testGetCallout() {
    // Set mock callout class 
    Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock()); 
    // This causes a fake response to be sent
    // from the class that implements HttpCalloutMock. 
    String response = AnimalLocator.getAnimalNameById(1);
    system.debug('Test Response1--->'+response);
    String expectedValue = 'chicken';
    System.assertEquals(expectedValue,response);
    String response2 = AnimalLocator.getAnimalNameById(2);
    system.debug('Test Response2--->'+response2);
    String expectedValue2 = 'duck';
    System.assertEquals(expectedValue2,response2);
}
}