You need to sign in to do that
Don't have an account?

HTTP and Basic Callout Trailhead Challange
Hello,
I am trying to solve the challange of the HTTP and Basic Callout module of Salesforce trailhead and I am having some queries in which you could point to the right direction:
1- The challange asked us to call this URL https://th-apex-http-callout.herokuapp.com/animals/:id in method getAnimalNameById... should that URL be in this form instead of the above https://th-apex-http-callout.herokuapp.com/animals?id ? Where id is a parameter in the URL.
2- When I tried to check the solution of the challange, Salesforce generated that error for me
"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."
despite that my class implementation has this method declared as public static String as below in the code snippet:
I would appreciate your help in this post.
Thank you,
Sinan
I am trying to solve the challange of the HTTP and Basic Callout module of Salesforce trailhead and I am having some queries in which you could point to the right direction:
1- The challange asked us to call this URL https://th-apex-http-callout.herokuapp.com/animals/:id in method getAnimalNameById... should that URL be in this form instead of the above https://th-apex-http-callout.herokuapp.com/animals?id ? Where id is a parameter in the URL.
2- When I tried to check the solution of the challange, Salesforce generated that error for me
"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."
despite that my class implementation has this method declared as public static String as below in the code snippet:
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); List<Object> animals = NULL; String returnValue = NULL; // if the request was successful, then parse the JSON response if (response.getStatusCode() == 200) { Map<String, Object> result = (Map<String, Object>) JSON.deserializeUntyped(response.getBody()); animals = (List<Object>) result.get('animals'); System.debug(animals); } if (animals.size() > 0 && animals != NULL && id < animals.size()) { returnValue = (String) animals.get(id); } return returnValue; } // end getAnimalNameById method } // end AnimalLocator class
I would appreciate your help in this post.
Thank you,
Sinan
Try
instead
All Answers
Try
instead
Thank you for your prompt reply. That tip helped me to solve the problem I am facing and getting the 500 points of the challange. Thanks. Sinan
I wrote the class in the following manner :
But facing
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.
Can anyone explain what is wrong in this ?
Regards,
Ajay
If you open the developer console and run the following what do you get back?
Following code works for me after checking the response.
Thanks for your help !!!
Regards,
Ajay
I've written the code in the below format.
public class AnimalLocator {
public class Animal{
public Animal Animal1;
}
public class Animal1 {
public Integer id;
public String name;
public String eats;
public String says;
}
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);
Animal anm = (Animal) JSON.deserialize(response.getBody(), Animal.class);
return anm.Animal1.name;
}
}
But I'm getting error as "Variable does not exist: name"
Can you guys plz help me out on this.....
Thanks in Advance !!!
Thanks in Advance !!!
This will define a variable named animal that points up your Animal1 class that has all of your expected fields. Then you would reference name by saying
Got it and it resolved my issue...
I've written test class after checking challenge facing the issue as per below.
Could you please check
Code :
public class AnimalLocator {
public class Animal {
public Integer id;
public String name;
public String eats;
public String says;
}
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);
Animal anm = (Animal) JSON.deserialize(response.getBody(),Animal.class);
string st = anm.name;
return st;
}
}
Error :
Challenge not yet complete
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.
Thanks in Advance !!
This has a variable named "animal" that you have to have in your main class. Then that variable contains data about the animal.
This allows you deserialize the data returned from the result as expected. By using
NOTE: When adding code please use the "Add a code sample" button (icon <>) to increase readability and make it easier to reference.
Animal Locator:
Mock Test Class: Test Class:
Sharing is caring!!!!
This does the same thing as the createParser does above (non-typed deserialization) but does it in a manner that is cleaner and easier to read. In production you'd want to have checks to make sure that the animal key in the jsonData map exists before trying to get the name key.
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');
System.debug('>>>>>>>'+id);
HttpResponse response = http.send(request);
Object animals;
String returnValue;
// parse the JSON response
if (response.getStatusCode() == 200) {
Map<String, Object> result = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
System.debug('>>>>>'+response.getBody());
animals = result.get('animal');
System.debug(animals);
}
if (animals != NULL ) {
Map<String, Object> result1 = (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(animals));
returnValue =(String) result1.get('name');
}
return returnValue;
}
}
Test Class :
@isTest
global class AnimalLocatorTest {
@isTest static void AnimalLocatorMock1() {
Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock());
string result = AnimalLocator.getAnimalNameById(3);
String expectedResult = 'chicken';
//System.assertEquals(result,expectedResult );
}
}
Mock Test :
@isTest
global class AnimalLocatorMock implements HttpCalloutMock{
global HTTPResponse respond(HTTPRequest request) {
// Create a fake response
HttpResponse response = new HttpResponse();
response.setHeader('Content-Type', 'application/json');
response.setBody('{"animal": {"id":99,"name":"trailhead","eats":"burritos","says":"more badgers"}}');
response.setStatusCode(200);
return response;
}
}
I faced this error and cannot find why it pops up... regardless in the log is visible that the method returns a string as requested. Any idea would be appreciated.
Challenge not yet complete in My Trailhead Playground 2
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.
The class The mock The test
And the log (sorry it is a bit long)
{ "animal": { "id": 1, "name": "chicken", "eats": "chicken food", "says": "cluck cluck" } }
And you need to change the code to parse it corretly.
{ "animal": { "id": 1, "name": "chicken", "eats": "chicken food", "says": "cluck cluck" } }
this worked for me too!
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> animalList = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
Map<String, Object> animal = (Map<String, Object>) animalList.get('animal');
animalName = (String)animal.get('name');
System.debug(animalList);
}
return animalName;
}
}
here is the code
Hopefully this info helps other folks!
I had tried out all the code snippets from this post, but was still getting the following -
Error :
Challenge not yet complete
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.
After checking the logs I noted the error:
10:37:10:010 FATAL_ERROR System.CalloutException: Unauthorized endpoint, please check Setup->Security->Remote site settings. endpoint = https://th-apex-http-callout.herokuapp.com/animals/99
Adding the Remote Site 'https://th-apex-http-callout.herokuapp.com' resolved my error and I was able to pass the challenge.
You have resolved my issue...
I was figuring out this issue from last 3-4 hr and getting same error continously...
Thankyou so much!!
:)
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.
Follow these steps , Before writing code
=================
From Setup, enter Remote Site Settings in the Quick Find box, then click Remote Site Settings.
Click New Remote Site.
For the remote site name, enter animals_http.
For the remote site URL, enter https://th-apex-http-callout.herokuapp.com. This URL authorizes all subfolders for the endpoint, like https://th-apex-http-callout.herokuapp.com/path1 and https://th-apex-http-callout.herokuapp.com/path2.
For the description, enter Trailhead animal service: HTTP.
Click Save & New.
For the second remote site name, enter animals_soap.
For the remote site URL, enter https://th-apex-soap-service.herokuapp.com.
For the description, enter Trailhead animal service: SOAP.
Click Save.
This approach in AnimalLocator does the trick for me
// parse the JSON response
if (response.getStatusCode() == 200) {
Map<String, Object> result = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
System.debug('>>>>>'+response.getBody());
animals = result.get('animal');
System.debug(animals);
}
if (animals != NULL ) {
Map<String, Object> result1 = (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(animals));
returnValue =(String) result1.get('name');
}
return returnValue;
}
However, this approach didn't lead to the accomplished challenge.
if (response.getStatusCode() == 200) {
Map<String, Object> r = (Map<String, Object>) JSON.deserializeUntyped(response.getbody());
Map<String, Object> animal = (Map<String, Object>)r.get('animal');
animalName = string.valueof(animal.get('name'));
}
return animalName;
Mock:
...
response.setBody('{"animal": {"id":0, "name": "majestic badger"}}');
...
"Challenge not yet complete in myForsePlayground
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."
Even though my code was all good. 100% coverage and bla....and the bloody treason : was ...coz
I did not have the Remote Site Settings ...which i dont think was in the challenge steps ......navigate to setup search "Remote Site Settings"
enter follwing
Remote site name: calloout
Remote site url : https://th-apex-http-callout.herokuapp.com you are all set to go..
The code which was as below but without the above setting the above error...
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 read this whole post and tried all the alternatives that you put, until I found a final combination, so I'm going to post what I did to make it work and validate the trailhead challenge:
Step 1
---------
Muthu kumar 53
Follow these steps , Before writing code
=================
From Setup, enter Remote Site Settings in the Quick Find box, then click Remote Site Settings.
Click New Remote Site.
For the remote site name, enter animals_http.
For the remote site URL, enter https://th-apex-http-callout.herokuapp.com. This URL authorizes all subfolders for the endpoint, like https://th-apex-http-callout.herokuapp.com/path1 and https://th-apex-http-callout.herokuapp.com/path2.
For the description, enter Trailhead animal service: HTTP.
Click Save & New.
For the second remote site name, enter animals_soap.
For the remote site URL, enter https://th-apex-soap-service.herokuapp.com.
For the description, enter Trailhead animal service: SOAP.
Click Save.
Step 2
---------
Write the classes and methods as detailed below, inside the Developer console and in 3 different classes:
first class
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');
System.debug('>>>>>>>'+id);
HttpResponse response = http.send(request);
Object animals;
String returnValue;
// parse the JSON response
if (response.getStatusCode() == 200) {
Map<String, Object> result = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
System.debug('>>>>>'+response.getBody());
animals = result.get('animal');
System.debug(animals);
}
if (animals != NULL ) {
Map<String, Object> result1 = (Map<String, Object>) JSON.deserializeUntyped(JSON.serialize(animals));
returnValue =(String) result1.get('name');
}
return returnValue;
}
}
Second Class
@isTest
global class AnimalLocatorTest {
@isTest static void AnimalLocatorMock1() {
Test.setMock(HttpCalloutMock.class, new AnimalLocatorMock());
string result = AnimalLocator.getAnimalNameById(3);
String expectedResult = 'chicken';
//System.assertEquals(result,expectedResult );
}
}
Third class
@isTest
global class AnimalLocatorMock implements HttpCalloutMock{
global HTTPResponse respond(HTTPRequest request) {
// Create a fake response
HttpResponse response = new HttpResponse();
response.setHeader('Content-Type', 'application/json');
response.setBody('{"animal": {"id":99,"name":"trailhead","eats":"burritos","says":"more badgers"}}');
response.setStatusCode(200);
return response;
}
}
After creating the 3 classes, do "save all" in the console menu, then in the "Test" menu, select the "Run All" option, you should have no errors.
Go back to the trailhead screen to validate the challenge, first refresh the screen and then press the validate button, you should earn the 500 points.
I hope this step by step works for you as it did for me.
I want to thank all those who posted their doubts and successes in this page, since it has been a great help to overcome the challenge.
Greetings and good luck.
- Add the url in remote site setting
If it solved your issue, please mark it as good answer.Thanks
Go to setup>Remote Site Settings>New Remote site > name of point ->>>> endpoint: url ->>>>>>https://th-apex-http-callout.herokuapp.com
Thanks
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'm still getting same error @Gabriel Tropea