Power BI Embedded using Angular and Azure Functions in Java

Siva Desaraju
9 min readAug 18, 2020

--

In this blog, we will see how to use Power BI Embedded in an angular application with an Azure function written in Java to access the Power BI REST APIs.

We will use a locally installed instance of SQL Server as the data source and Microsoft’s adventure works sample database. For the purposes of this demo, we will setup a refresh schedule using on-premises data gateway in personal mode. In production, you would need to set up an on premises data gateway.

You can get the complete source code for this example here:

Angular Application Codehttps://github.com/sdesa/powerbi-app

Token Functionhttps://github.com/sdesa/powerbi-app-functions

Here are the prerequisites as we walk through this:

Angular: v8 or above

Java: Java 1.8+

VS Code

SQL Server Express Edition

Let’s get the ball rolling…

There are 2 ways to embed Power BI content into your application:

Embed for your organization aka User owns data :

This requires your users to have individual Power BI licenses. Use this approach to share your reports within your organization.

Authentication is by the user logging in, and needs to be granted access to the report.

Embed for your customers aka App owns data :

This does not require your users to have a Power BI license. Use this approach to share your reports to external users from within your application and do not expect them to have a Power BI license.

Authentication is by a service principal or a master user account that is shared across multiple users.

We will be implementing the “Embedding for your customers” solution here. The picture below shows a high level overview of the architecture.

High level architecture
  1. Create a Power BI Report using Power BI Desktop Pro/Premium*
  2. Import data option should be good unless your use case needs live query
  3. Create a workspace in Power BI and publish the report to the workspace
  4. From the angular application, fetch the access token using a simple Azure Function
  5. Embed the report using Power BI JavaScript SDK
  6. Setup scheduled refresh of the dataset using the data gateway

*Required to publish the report to Power BI Server and other features.

We will walk through steps to implement this, with a brief explanation of why we are doing along each step.

Step 1. Register an application in Azure Active Directory (AAD)/Create the Service Principal

As explained earlier, authentication to the Power BI REST APIs is through a service principal that we will use independent of the user logging into the application. This is like a service account that is granted permission to Power BI. We need to register an application in Azure before we can create an SP. Let us look at the steps on how to register an application and creating the SP.

Go to https://portal.azure.com and click on Azure Active Directory/App Registration or simply search for App Registrations in the search bar.

Click on New Registration.

Give it a name (in my case, I named it powerbiapp), leave the defaults and click “Register”.

Registering a new application

Once the application is created, save the application id, object id and tenant id, you will need it later.

Click on Certificates and Secrets and create a new client secret.

New client certificate

Once done, save the client secret, you will need it later as well.

If you prefer CLI:

C:\> az ad app create --display-name powerbiappspcC:\> az ad sp create --id <<appId from the output of the above command>>C:\> az ad app credential reset --id <<appId from the output of the above command>> --append

Step 2. Create a new Security Group called PowerBI_API_Users

We will create an AD group that will granted access to Power BI APIs. This is the recommended and probably the only way you can assign the service principal to be granted access to the APIs.

To create the group go to:

Azure Active Directory and Click on Create New Group

New group

Add the newly created SP as a member and click Create.

If you prefer CLI:

C:\> az ad group create --display-name PowerBI_API_Users --mail-nickname PowerBI_API_UsersC:\> az ad group member add --group PowerBI_API_Users --member-id <<ObjectId of the SP created>>

Tip: You can get the object id from the az ad sp list command in case you forgot to save it.

Step 3. Enable Service Principal in the tenant settings

By default, allowing service principals accessing the Power BI APIs in your tenant is disabled for security reasons. So, you will need to explicitly enable it in your tenant. You can follow the instructions at the link below on how to enable it.

https://docs.microsoft.com/en-us/power-bi/guidance/admin-tenant-settings

Once you enable SPs, you will grant access to the group we created earlier, the PowerBI_API_users group.

Tenant admin settings

Step 4. Create a workspace in Power BI

You will need a space to hold your reports, a workspace. This is where you will publish your reports. Every user and service principal needs to be explicitly granted access to this workspace to view/edit the content in this workspace, this is what we will be doing here.

Go to your powerbi subscription, go to Workspaces and click on “Create a Workspace”.

New workspace

Give it a name, and add specific users that you want granted access to this workspace. Click Save.

Once the workspace is created, click on the Access link and grant the Power_BI_Users group you created in Step 2, member access to your workspace and click Add.

Access

Step 5. Create a sample report

Create a Power BI Report in Power BI Desktop. This is the report we will be embedding in the angular application.

I have used Microsoft’s Adventure Works for the solution. Set up instructions can be found here: https://docs.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver15&tabs=ssms

You can get the sample report here if you prefer to skip creating the report.

From Power BI Desktop, click on Get Data and provide the connection details. Leave “Import” selected.

Create a new report

For this example, I pulled FactInternetSales and DimSalesTerritory from AdventureWorks and created a simple chart shown below:

Sample report

At this point, you should have the report and the dataset ready to be published.

Save the report and publish it to the workspace we just created.

Once you publish the report, your workspace when you navigate to app.powerbi.com will look like this.

Workspace page

Step 6. Create a sample angular application with a report component and a service to fetch the token (we will look at why we need a token later)

C:\> ng new powerbiangularappC:\> ng g c report --module=app.moduleC:\> ng g s bi

Replace all the content in app.component.html with this line below:

<router-outlet></router-outlet>

Add these lines to your Routes constant in app-routing.module.ts

{path: ‘report’,component: ReportComponent}

After you have done this, run “ng serve” from you command prompt and navigate to https://localhost:4200. You should see a page like this below.

Base angular application report page

That was a breeze!

Step 7. Add the PowerBI JavaScript SDK to your angular application (If you downloaded the angular application from my repo, you can skip this step)

Navigate to your angular application and run:

C:\powerbiangularapp> npm install --save powerbi-client

Add this line to report.component.ts where you want to embed the report

import * as pbi from ‘powerbi-client’;

See the references section for the SDK official docs

Step 8. Create a function to access the embed token

Before you can embed the report in your angular application, you would need to get the access token using the service principal you created earlier, and then use that access token to get the report details that you need to embed the report and also an embed token to access the report. I have created a simple function with instructions on what you need to replace before you can run the function. I have shown snippets of code from the samples but the entire function source code and instructions for the function here. Be sure to checkout the README file.

Get the access token:

Get the access token (code can be accessed here)

Get the report details (embed URL, datasetId and reportId):

Get the report details (code can be accessed here)

Get the embed token:

Get the embed token (code can be accessed here)

Once you have cloned the source code, you can run the function from within VS Code by hitting F5 or Ctrl + F5.

Step 9. Finally add code to embed the report

Add the following lines of code to repot.component.html. We are adding a placeholder for the iframe that will hold the report.

<div id=”embedReport” class=”resp-iframe” style=”height: 800px; width: 1600px; “></div>

Let us look at the .ts file and the steps we need to get the report.

The code and the comments below explain what needs to go into the .ts file to render the report.

Finally, import the HttpClientModule to your app.module.ts.

Note that you need to add a proxy.config.json to avoid CORS issues to access the function. For this config to be picked up, you should pass the config file at startup. This is the command you will use.

{“/api/*”: {“target”: “http://localhost:7071/",“secure”: false,“logLevel”: “debug”}}ng serve --proxyConfig=proxy.conf.json

The variables groupId and reportId in the application need to be replaced by the group id and report id of your instance which you can get from the URL of your power bi report. See the screenshot below:

Here is how to get the report Id and group Id

Step 10. Access your report from the angular application

Once your angular application is running, navigate to http://localhost:4200/report to see your report! Your screen should look like this.

Accessing the report from angular

That is it! Your angular application now has the power bi embedded report which has data sourced from your on premise network. Your refresh schedule will keep the dataset up to date which we will look at as the next step.

Step 11. Setup refresh

Once this is all working end to end, you can install an on premise gateway by following the instructions here and setup your data set to refresh on a schedule.

--

--