Salesforce Analytics API with AngularJS – PART 1

Salesforce has released Salesforce1 Reporting REST API in its winter 14 release. The API lets you integrate the data into any web or mobile application, inside or outside the Salesforce platform. For example you have a web or a mobile application where you have to display a report or a graph from the data fetched from your Salesforce org, but processing a large set of data using code and queries will be little slow so let Salesforce do this job for you, create a report the way you want and fetch the data directly from Report.

Detailed information about Analytic API can be found in Salesforce douments Analytics API. In this blog we see how to decode the data and the structure of the report and call Analytic API from AngularJS, because in most of web/mobile application we either use AngularJs or JQuery.

Let’s Begin

I created a matrix report which shows total expected revenue,amount of a Account where opportunity grouped by Type. Below is the screenshot of the report
opportunity report

To get the report metadata and data you need report id and session id, report id you can query like any other object SELECT Id,Name FROM Report WHERE Name = ‘Report Name’ . Session id you can get from response of your authentication since for this example I am using Visualforce Page I got the session id directly from {!$Api.Session_ID}

To make a GET or a POST call for the REST API depends totally on the requirement. GET is simply fetching the report details and in POST call you can pass dynamic filters for the reports in the body, that we will see in later parts. Below is the code which makes a REST call to Salesforce and fetches the report data

$http.get('/services/data/v29.0/analytics/reports/00--(ReportId)--Zd?includeDetails=true',{headers: {'Authorization': 'Bearer {!$Api.Session_ID}'}}).success(function(data, status, headers, config) {
    $scope.accountList     = data.groupingsDown.groupings;
    $scope.OpportunityType = data.groupingsAcross.groupings;
    $scope.dataList        = data.factMap;
}).error(function(data, status, headers, config) {
    $log.error(JSON.stringify(status));
});

The output JSON will be almost like this

{
  "allData": true,
  "factMap": {},
  "groupingsAcross": {},
  "groupingsDown": {},
  "hasDetailRows": true,
  "reportExtendedMetadata": {
    "aggregateColumnInfo": {},
    "detailColumnInfo": {},
    "groupingColumnInfo": {}
  },
  "reportMetadata": {
    "reportFilters": [],
    "reportFormat": "MATRIX",
    "reportType": {}
  }
}

From the output factMap will contain data, reportFilters will contain the filters and groupingsAcross and groupingsDown will contain the grouping description. The decoded structure of report will be like this
Grouping

In our example groupingsDown will contain Accounts and groupingsAcross will contain opportunity type which you can see clearly from the assignment of array I have done

$scope.accountList     = data.groupingsDown.groupings;
$scope.OpportunityType = data.groupingsAcross.groupings;

A grouping object structure will be like -> { key:””, label:”” , value:”” } . For example data.groupingsDown.groupings[0].key, data.groupingsDown.groupings[0].label and data.groupingsDown.groupings[0].value will return 0,First Account name and Id of that account respectively

factMap will contain data in the below format

"factMap": {
    "3!0": {
      "aggregates": [
        {
          "label": "$124,000.00",
          "value": 124000
        },
        {
          "label": "$200,000.00",
          "value": 200000
        }
      ],     
    },
.
.
.
}

This factMap will be a key value pair, where 3!0 will be the key which represent 4th account from the example, against the summary of first grouping which is Existing Customer – Upgrade. aggregates will be the array of all the formulas, which in our example is Sum of Expected Revenue and Sum of Amount.
Lets see this in code

// Account  -> Express Logistics and Transport, index 3 in groupingDown
// Grouping - > Existing Customer - Upgrade, index 0 in groupingAcross
var summaries = data.factMap['3!0'];
summaries.aggregates[0].label; // textual representation of Sum of Expected Revenue
summaries.aggregates[0].value; // numeric representation of Sum of Expected Revenue 

summaries.aggregates[1].label; // textual representation of Sum of Amount
summaries.aggregates[1].value; // numeric representation of Sum of Amount 

I created a sample page which contain a drop down of Account Names and on change populates a table with the summary values from the report.
Sample

The code for on Change method of the drop down is

$scope.items = []; // Array which contain data for the table 
$scope.fetchCurrentAccountValues = function(){
	$scope.items = [];
	var tempKey = $scope.account.key; // ng-model for the drop down
	angular.forEach($scope.OpportunityType,function(groupingAccrossKey,key){
			var localLoopVar = tempKey;
			tempKey = tempKey+'!'+groupingAccrossKey.key;
				
			var dataObject = $scope.dataList[tempKey];
			  			
	 $scope.items.push({Type:groupingAccrossKey.label,Exp:dataObject.aggregates[0].label,Amt:dataObject.aggregates[1].label});
			tempKey = localLoopVar;
			});
			  		
	}
}	

This concludes the basics of reporting API. In later parts I will show you how to use dynamic filters and google charts with Analytic API.
Note : Please read the Salesforce guide of Analytic API for detailed understanding and limitations

Advertisements

One thought on “Salesforce Analytics API with AngularJS – PART 1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s