Temboo can help you reduce the complexity of API responses. Just specify one or more Output Filters when you call a Choreo.
It’s a filter that returns only the data that you care about!
Many APIs return a lot of complex JSON or XML data that can be difficult to parse. Let's take a look at how we can use Output Filters with the Android SDK to make API responses easier to work with.
Make sure that you've been through the Android getting started tutorial. In the following steps, we'll build upon that tutorial by adding Output Filters.
1In the getting started tutorial, we demonstrated how to display Latitude and Longitude on your Android device (or emulator). To setup our Output Filters, let's print out all of the returned data at once. Go ahead and replace the Latitude and Longitude return
statement in your GeocodingTask
class with the following:
return geocodeByAddressResults.getOutputs().toString();
2In your activity_main.xml
click on the TextView
you previously used to show the Latitude and Longitude. In the Properties panel on the bottom-right of the editor, find the id property. Click to the right of it and replace with:
@+id/outputs
3Then in your ActivityMain
class, replace the id
in the onCreate
method as shown below:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); TextView textView = (TextView) findViewById(R.id.outputs); new GeocodingTask(textView).execute(); }
4Run the code and take a look at your Android device (or emulator). See the XML response? There's a lot of data!
5What if the only information we need for our application is the formatted_address
, and a collection of individual address_components
that make up that address? Introducing Output Filters will allow us to extract only those data elements by adding just two lines of code. In your GeocodingTask
class, add the following lines before the
geocodeByAddressChoreo.execute();
method in the doInBackground()
function:
// add an output filter to extract the full address geocodeByAddressInputs.addOutputFilter("address", "/GeocodeResponse/result/formatted_address", "Response"); // add an output filter to extract the collection of address long_name components geocodeByAddressInputs.addOutputFilter("components", "/GeocodeResponse/result/address_component/long_name", "Response");
6Run the code again and take a look at your Android device (or emulator). You should see the full address, as well as a collection of the long_name
components from the XML.
{address=104 Franklin Street, New York, NY 10013, USA, components=["104","Franklin Street","Lower Manhattan","Manhattan","New York","New York County","New York","United States","10013"]}
Before showing some neat tricks to access the individual elements in the data, let's take a look at how the filter is created. As we saw above, each Output Filter is constructed with three parameters, in the format:
ChoreoInputSet.addOutputFilter(result_label, data_path, choreo_output)
It may look confusing at first, but let’s step through recreating the two Output Filters from scratch to understand what's happening.
1A ChoreoInputSet
object is used to specify the inputs that will be passed to the Choreo. Output Filters are also a type of Choreo input, so we'll add our inputs to the ChoreoInputSet
object. To find the input set that we used to add the Geocoding Output Filters, just look back at the following line in your code:
// Get an InputSet object for the choreo GeocodeByAddressInputSet geocodeByAddressInputs = geocodeByAddressChoreo.newInputSet();
After identifying the input that we'd like to filter, add .addOutputFilter
as shown below.
geocodeByAddressInputs.addOutputFilter(result_label, data_path, choreo_output);
2A result_label
is anything we want it to be! It can be data123
or apple
or Homer
, as long as each output filter has a unique result_label
of numbers or letters. This is how we tell Temboo to label a piece of result information when it is returned. In our example, we called our collection of address elements “components”
. We called the full address "address"
.
3The data_path
is used to identify, via XPath or a JSON path, the location of the particular item(s) that you want your Output Filter to return. For a more in depth explanation of data paths and data types, check out our guide on JSON & XML for Output Filters. Here are the paths that we used when specifying our Output Filters earlier.
/GeocodeResponse/result/address_component/long_name /GeocodeResponse/result/formatted_address
4The Choreo_output
is the name of the Choreo output data that we're applying our filter to. These names can be found in each Choreo's output section on our website. In most cases, the relevant Choreo output name will be Response, like in the screenshot below. However, as you can see we can also retrieve Latitude and Longitude in this particular Choreo.
5When we combine all of this information, we have two Output Filters. One returns only the full formatted address as a string, and another returns a collection of elements that make up the address as a list.
// Get the full address as a string geocodeByAddressInputs.addOutputFilter("address", "/GeocodeResponse/result/formatted_address", "Response" ); // Get the components of the address as a list geocodeByAddressInputs.addOutputFilter("components", "/GeocodeResponse/result/address_component/long_name", "Response" );
Previously, we displayed all of the filtered outputs together on the Android device (or emulator) screen. However, it can be even more useful to access each element individually.
1Since there is only one piece of data contained in the filter "address"
, we can use the same steps above to display the string to our Android device (or emulator) screen by using the getResultString()
method. Replace the line return geocodeByAddressResults.getOutputs().toString();
in your GeocodingTask
class, with the following:
return geocodeByAddressResults.getResultString("address");
2In your activity_main.xml
click on the TextView
you previously called outputs
. In the Properties panel on the bottom-right of the editor, find the id property. Click to the right of it and replace with:
@+id/address
3Then in your ActivityMain
class, change the id
from outputs
to address
in onCreate
method as shown below:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); TextView textView = (TextView) findViewById(R.id.address); new GeocodingTask(textView).execute(); }
4We noted before that the "components"
data is a collection of individual elements that make up the address. To access those elements, we'll use a for
loop to iterate through a list of elements retrieved from the getResultList("components")
method, then print each on a new line in our console. Any of the items we print to console, can also be displayed following the steps above. Let's give it a try:
Above the line return geocodeByAddressResults.getResultString("address");
in your GeocodingTask
class, add the following lines of code:
//loop through each element returned by the "components" output filter and print to the console for(int i = 0; i < geocodeByAddressResults.getResultList("components").length(); i++) { System.out.println(geocodeByAddressResults.getResultList("components").get(i)); }
5If you run the code and look at your Android device (or emulator), you'll see the full formatted address displayed like the screenshot below, while each of the individual elements from our address will be printed to the console:
The complete version of the GeocodingTask
class takes advantage of two Output Filters. It should look like this:
package temboo.androidtembootest; import android.os.AsyncTask; import android.util.Log; import android.widget.TextView; import com.temboo.Library.Google.Geocoding.GeocodeByAddress; import com.temboo.Library.Google.Geocoding.GeocodeByAddress.GeocodeByAddressInputSet; import com.temboo.Library.Google.Geocoding.GeocodeByAddress.GeocodeByAddressResultSet; import com.temboo.core.TembooSession; /** * An AsyncTask that will be used to interact with Temboo */ class GeocodingTask extends AsyncTask<Void, Void, String> { private TextView textView; public GeocodingTask(TextView textView){ this.textView = textView; } @Override protected String doInBackground(Void... arg0) { try { // Instantiate the Choreo, using a previously instantiated TembooSession object, eg: TembooSession session = new TembooSession("ACCOUNT_NAME", "APP_NAME", "APP_KEY"); GeocodeByAddress geocodeByAddressChoreo = new GeocodeByAddress(session); // Get an InputSet object for the choreo GeocodeByAddressInputSet geocodeByAddressInputs = geocodeByAddressChoreo.newInputSet(); // Set inputs geocodeByAddressInputs.set_Address("104 Franklin Street, New York City"); // add an output filter to extract the full address geocodeByAddressInputs.addOutputFilter("address", "/GeocodeResponse/result/formatted_address", "Response"); // add an output filter to extract the collection of address long_name components geocodeByAddressInputs.addOutputFilter("components", "/GeocodeResponse/result/address_component/long_name", "Response"); // Execute Choreo GeocodeByAddressResultSet geocodeByAddressResults = geocodeByAddressChoreo.execute(geocodeByAddressInputs); //loop through each element returned by the "components" output filter and print to the console for(int i = 0; i < geocodeByAddressResults.getResultList("components"). length(); i++){ System.out.println(geocodeByAddressResults.getResultList("components"). get(i)); } //display the full address in TextView return geocodeByAddressResults.getResultString("address"); } catch(Exception e) { // if an exception occurred, log it Log.e(this.getClass().toString(), e.getMessage()); } return null; } protected void onPostExecute(String result) { try { // Update the U textView.setText(result); } catch(Exception e) { // if an exception occurred, show an error message Log.e(this.getClass().toString(), e.getMessage()); } } }
You should now see individual outputs for each of the address "components"
printed to the console, and the full "address"
as a string printed in your Android app.
We've filtered some data! You can specify as many Output Filters as you need for each Choreo, so why not try adding your own third output filter to this example? If you'd like to try something different, you can try filtering the output from any of our 2000+ Choreos.
Once you've got your code up and running, you're ready to move on and do more. From monitoring your running applications, to moving your generated Temboo code to your preferred development environment and sharing it with colleagues, collaborators and friends - we've got you covered.
We're always happy to help. Just email us at support@temboo.com, and we'll answer your questions.