Bold BI Dashboards embedding in Angular using Embedded SDK
A GitHub link has been provided to get the sample application, which demonstrates the rendering of the dashboard available on your Bold BI server. This is followed by steps to create your own embedding application in Angular.
NOTE: The best way to get started would be to read the Getting Started section of the documentation first. The
Getting Startedguide provides you with enough information that you need to know before working on the sample. To explore the Angular embedding sample in Bold BI v3.2.16, please refer to the Angular with ASP.NET Core for more details.
Prerequisites
NOTE: Node.js versions 18.18 to 20.15 are supported.
How to run the sample
-
Please get the Angular with ASP.NET Core sample from GitHub.
-
Please make sure you have activated embed authentication on the
embed settingspage. If it is not currently activated, please refer to the image or detailed instructions below to enable it.
-
To download the
embedConfig.jsonfile, please click on the following link for reference. Additionally, you can view the accompanying image for visual guidance.

-
Please copy the downloaded
embedConfig.jsonfile and paste it into the designated location within the application. Please make sure to place it in the application as shown in the following image.
ServerUrl Dashboard Server BI URL (eg: http://localhost:5000/bi, https://demo.boldbi.com/bi) SiteIdentifier For the Bold BI Enterprise edition, it should be like site/site1. For Bold BI Cloud, it should be an empty string. UserEmail UserEmail of the Admin in your Bold BI, which would be used to get the dashboard list. EmbedSecret Get your EmbedSecret key from the Embed tab by enabling the Enable embed authenticationin the Administration pageEnvironment Your Bold BI application environment. (If it is a cloud analytics server, use `BoldBI.Environment.Cloud`; if it is your server, use `BoldBI.Environment.Enterprise`) DashboardId Item ID of the dashboard to be embedded in your application. ExpirationTime Token expiration time. (In the 'EmbedConfig.json' file, the default token expiration time is 10000 seconds) -
In this scenario, the Angular application functions as a client, while the ASP.NET Core application functions as a server. This is because you must configure the properties in the
app.component.tsfile.
-
Open your Angular with ASP.NET Core project in
Visual Studio Codeand install all dependent packages by using the following commandnpm install. -
Execute the command
dotnet restoreto restore the necessary packages. Once the packages have been restored, use thedotnet buildcommand to build the project. -
Run your Angular with ASP.NET Core sample by using the command
dotnet runin Visual Studio Code.
How this sample works
-
The
renderDashboardmethod will be invoked from thengOnInit()function based on the configured embedConfig values in thedashboard.component.tsfile.
-
Before rendering, call the
tokenGenerationUrl, which redirects to theTokenGenerationaction in theBoldBIEmbedController. This action generates the access token using the providedembedDetailsof the ASP.NET Core application.

-
Once the token is generated, it will be returned to the
dashboard.component.tsfile and the dashboard will start to render it.
Steps to create new Angular application to embed dashboard
-
Please create a folder in the desired location and open it in Visual Studio Code.
-
Please open the terminal in Visual Studio Code. Please refer to the following image.

-
To create a new project, execute this command in the terminal.
dotnet new angular -
Please ensure that you have enabled embed authentication on the
embed settingspage. If it is not currently enabled, please refer to the following image or detailed instructions to enable it.
-
To download the
embedConfig.jsonfile, please click on the provided link . Furthermore, you can also refer to the accompanying image for visual assistance.

-
Please copy the downloaded
embedConfig.jsonfile and paste it into the designated location within the application. Kindly make sure to place it in the application exactly as shown in the following image.
-
Create a new folder called
Models. Create a model class asDataClass.csto define the following properties. These properties are used to get the dashboard details from the server.Execute the following commands in the terminal to add the necessary references to the project:
dotnet add package Newtonsoft.Jsonanddotnet add package System.Runtime.Serialization.Primitives. Ensure theSystem.Runtime.SerializationandNewtonsoft.Jsonnamespaces are in theDataClass.csmodel file.[DataContract] public class EmbedClass { [DataMember] public string embedQuerString { get; set; } [DataMember] public string dashboardServerApiUrl { get; set; } } public class TokenObject { public string Message { get; set; } public string Status { get; set; } public string Token { get; set; } } public class Token { [JsonProperty("access_token")] public string AccessToken {get;set;} [JsonProperty("token_type")] public string TokenType {get;set; } [JsonProperty("expires_in")] public string ExpiresIn {get; set;} [JsonProperty("email")] public string Email {get;set;} public string LoginResult {get;set;} public string LoginStatusInfo {get;set;} [JsonProperty(".issued")] public string Issued { get; set; } [JsonProperty(".expires")] public string Expires { get; set; } } public class EmbedDetails { public string Environment { get; set; } public string SiteIdentifier { get; set; } public string ServerUrl { get; set; } public string EmbedSecret { get; set; } public string UserEmail { get; set; } public string EmbedType { get; set; } public string DashboardId { get; set; } } -
Create another model class as
GlobalAppSettings.csto define the following properties. These properties maintain theembedConfig.jsonfile object within theGlobalAppSettings.public class GlobalAppSettings { public static EmbedDetails EmbedDetails { get; set; } } -
Create a new controller as
BoldBIEmbedController.cs. In theControllers\BoldBIEmbedController.cs, To get particular dashboard details, define the APIGetDetails()which uses theGetSignatureUrl()method to generate the algorithm. In this API,embedQuerString,userEmailand the value from theGetSignatureUrl()method are appended as query parameters in the URL to get details of a particular dashboard.[ApiController] [Route("api/[controller]")] public class BoldBIEmbedController : Controller { [HttpGet] [Route("GetData")] public IActionResult GetData() { var jsonData = System.IO.File.ReadAllText("embedConfig.json"); return Ok(jsonData); } [HttpGet] [Route("GetDashboards")] public string GetDashboards() { var token = GetToken(); using (var client = new HttpClient()) { client.BaseAddress = new Uri(GlobalAppSettings.EmbedDetails.ServerUrl); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Add("Authorization", token.TokenType + " " + token.AccessToken); var result = client.GetAsync(GlobalAppSettings.EmbedDetails.ServerUrl + "/api/" + GlobalAppSettings.EmbedDetails.SiteIdentifier + "/v2.0/items?ItemType=2").Result; string resultContent = result.Content.ReadAsStringAsync().Result; return resultContent; } } public Token GetToken() { using (var client = new HttpClient()) { client.BaseAddress = new Uri(GlobalAppSettings.EmbedDetails.ServerUrl); client.DefaultRequestHeaders.Accept.Clear(); var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("grant_type", "embed_secret"), new KeyValuePair<string, string>("Username", GlobalAppSettings.EmbedDetails.UserEmail), new KeyValuePair<string, string>("embed_secret", GlobalAppSettings.EmbedDetails.EmbedSecret) }); var result = client.PostAsync(GlobalAppSettings.EmbedDetails.ServerUrl + "/api/" + GlobalAppSettings.EmbedDetails.SiteIdentifier + "/token", content).Result; string resultContent = result.Content.ReadAsStringAsync().Result; var response = JsonConvert.DeserializeObject<Token>(resultContent); return response; } } } -
In the
Controllers\BoldBIEmbedController.cs, To get particular dashboard details, define an APIAuthorizationServer()which uses the methodGetSignatureUrl()to generate the algorithm. In this API, theembedQuerString,userEmailand the value from theGetSignatureUrl()method are appended as query parameters in the URL to get details of a particular dashboard. With these details, therenderDashboard()method is called in the angular application.
[HttpPost] [Route("AuthorizationServer")] public string AuthorizationServer([FromBody] object embedQuerString) { var embedClass = Newtonsoft.Json.JsonConvert.DeserializeObject<EmbedClass>(embedQuerString.ToString()); var embedQuery = embedClass.embedQuerString; // User your user-email as embed_user_email embedQuery += "&embed_user_email=" + GlobalAppSettings.EmbedDetails.UserEmail; //To set embed_server_timestamp to overcome the EmbedCodeValidation failing while different timezone using at client application. double timeStamp = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; embedQuery += "&embed_server_timestamp=" + timeStamp; var embedDetailsUrl = "/embed/authorize?" + embedQuery + "&embed_signature=" + GetSignatureUrl(embedQuery); using (var client = new HttpClient()) { client.BaseAddress = new Uri(embedClass.dashboardServerApiUrl); client.DefaultRequestHeaders.Accept.Clear(); var result = client.GetAsync(embedClass.dashboardServerApiUrl + embedDetailsUrl).Result; string resultContent = result.Content.ReadAsStringAsync().Result; return resultContent; } } public string GetSignatureUrl(string queryString) { if (queryString != null) { var encoding = new System.Text.UTF8Encoding(); var keyBytes = encoding.GetBytes(GlobalAppSettings.EmbedDetails.EmbedSecret); var messageBytes = encoding.GetBytes(queryString); using (var hmacsha1 = new HMACSHA256(keyBytes)) { var hashMessage = hmacsha1.ComputeHash(messageBytes); return Convert.ToBase64String(hashMessage); } } return string.Empty; } -
Open the
Program.csfile and add the following code sample beforeapp.UseHttpsRedirection(). To read theembedConfig.jsonfile in order to utilize it in the controller. The existingMapControllerRoutepattern inside thecontrollername andactionname changed as follows. Ensure the usingusing Newtonsoft.Jsonnamespaces in theProgram.csfile.app.UseCors(corsPolicyBuilder => corsPolicyBuilder .AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); string basePath = AppDomain.CurrentDomain.BaseDirectory; string jsonString = System.IO.File.ReadAllText(Path.Combine(basePath, "embedConfig.json")); GlobalAppSettings.EmbedDetails = JsonConvert.DeserializeObject<EmbedDetails>(jsonString); app.MapControllerRoute( name: "default", pattern: "{BoldBIEmbed}/{action=GetData}/{id?}"); -
Create a new file and name it
package.json. It is essential to install the packages listed in the dependencies section below.{ "name": "angular-sample", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test" }, "private": true, "dependencies": { "@boldbi/boldbi-embedded-sdk": "^6.4.6", "@angular/animations": "^14.0.0", "@angular/common": "^14.0.0", "@angular/compiler": "^14.0.0", "@angular/core": "^14.0.0", "@angular/forms": "^14.0.0", "@angular/platform-browser": "^14.0.0", "@angular/platform-browser-dynamic": "^14.0.0", "@angular/router": "^14.0.0", "rxjs": "~7.5.0", "tslib": "^2.3.0", "zone.js": "~0.11.4", "@angular-devkit/build-angular": "^14.0.0", "@angular/cli": "^14.0.6", "@angular/compiler-cli": "^14.0.0" } } -
Open the folder
ClientApp\src\appand create adashboard-listingfolder with adashboard-listing.component.htmlanddashboard-listing.component.tsfiles in it. In theapp.component.tsfile replace the following code, define the mandatory properties, and invoke thengOnInit()which is implemented in thedashboard-listing.component.tsmethod as follows.import { Component } from '@angular/core'; import { appService } from './app.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', }) export class AppComponent { //ASP.NET Core application would be run on https://localhost:7210;http://localhost:5279, which needs to be set as `apiHost` public apiHost = "https://localhost:7210/"; //Url of the GetDetails action in ValuesController of the ASP.NET Core application public authorizationUrl = "api/boldbiembed/authorizationserver"; //Url of the GetDashboards action in ValuesController of the ASP.NET Core application public getDashboardsUrl = "api/boldbiembed/getdashboards"; public getEmbedConfigUrl = "api/boldbiembed/getdata"; public embedConfig: any; public dashboards: any; public baseUrl: any; public dashboardServerApiUrl!: string; constructor(private _app: appService) { } ngOnInit() { } }
NOTE: Open the
launchSettings.jsonfile,applicationUrlis copied and pasted inapiHost.
-
In the
dashboard-listing.component.htmlfile, create the DOM element to render the dashboard and its list as follows.<div id="viewer-section"> <div id="dashboard"></div> </div> -
In the
Index.htmlfile, refer to the following cdn files in the<head>tag.<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Embedded BI</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="stylesheet" href="./assets/css/site.css" /> </head> <body><app-root></app-root></body> </html> -
In the
dashboard-listing.component.ts, you need to implement thengOnInit()andrenderDashboard()methods. In thengOnInit()method, assign value for thebaseUrlanddashboardServerApiUrl, which is used by therenderDashboard()method to render the dashboard. Invoke thegetDashboard()with the token to get the dashboard details and dashboard list from server.
import { Component, OnInit } from '@angular/core'; import { Item } from '../app'; import { appService } from '../app.service'; import { AppComponent } from '../app.component'; import { BoldBI } from '@boldbi/boldbi-embedded-sdk'; import { DashboardService } from '../dashboard.service'; @Component({ selector: 'app-dashboard-listing', templateUrl: './dashboard-listing.component.html', providers: [appService] }) export class DashboardListing implements OnInit { public dashboardsList!: Item[]; result: any; dashboard: any; embedConfig: any; constructor(private _app: appService, private _appComponent: AppComponent, private dashboardService: DashboardService) { } ngOnInit() { this._app.GetEmbedConfig(this._appComponent.apiHost + this._appComponent.getEmbedConfigUrl).subscribe(data => { this._appComponent.embedConfig = <any>data; this.dashboardService.setEmbedConfig(this._appComponent.embedConfig); if (this.dashboardService.embedConfig.Environment == "enterprise" || this.dashboardService.embedConfig.Environment == "onpremise") { this._appComponent.baseUrl = this.dashboardService.embedConfig.ServerUrl + "/" + this.dashboardService.embedConfig.SiteIdentifier; this._appComponent.dashboardServerApiUrl = this.dashboardService.embedConfig.ServerUrl + "/api/" + this.dashboardService.embedConfig.SiteIdentifier; } else { this._appComponent.baseUrl = this.dashboardService.embedConfig.ServerUrl; this._appComponent.dashboardServerApiUrl = this.dashboardService.embedConfig.ServerUrl + "/api"; }}) } } -
In the
getDashboard, the dashboard list is obtained from the server and passed to thedashboardDetails()method to render a dashboard.this._app.GetDashboards(this._appComponent.apiHost + this._appComponent.getDashboardsUrl). subscribe(data => { this._appComponent.dashboards = <any>data; this.dashboardsList = this._appComponent.dashboards; this.renderDashboard(this.dashboardsList[0]); }); -
Once the server sends the response to the
GetDashboards()of an angular application, this method returns the response to thengOnInit()method to call therenderDashboard()method. -
In the
renderDashboard()method, an instance is created to render a dashboard using theloadDashboard()method as follows.
renderDashboard(dashboard: Item) { this.dashboard = BoldBI.create({ serverUrl: this._appComponent.baseUrl, dashboardId: this.dashboardService.embedConfig.DashboardId, embedContainerId: "dashboard", embedType: this.dashboardService.embedConfig.EmbedType, environment: this.dashboardService.embedConfig.Environment, width: "100%", height: "100%", expirationTime: 100000, authorizationServer: { url: this._appComponent.apiHost + this._appComponent.authorizationUrl } }); console.log(this.dashboard); this.dashboard.loadDashboard(); } -
Open the
app.component.htmlfile and replace the following code.<body> <main class="dashboard_container"><router-outlet></router-outlet></main> </body> -
Open the
app.module.tsfile and replace the following code. The necessary modules and components are imported.import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { RouterModule } from '@angular/router'; import { appService } from './app.service'; import { AppComponent } from './app.component'; import { NavMenuComponent } from './nav-menu/nav-menu.component'; import { DashboardListing } from './dashboard-listing/dashboard-listing.component'; import { CounterComponent } from './counter/counter.component'; import { FetchDataComponent } from './fetch-data/fetch-data.component'; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot([ { path: '', component: DashboardListing }, ] ), HttpClientModule ], providers: [appService], declarations: [ AppComponent, DashboardListing, NavMenuComponent, CounterComponent, FetchDataComponent ], bootstrap: [AppComponent] }) export class AppModule { } -
Open the folder
ClientApp\src\appand create a new file calledapp.service.tsfile, include the following code.import { Injectable } from '@angular/core'; import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http'; import { HashLocationStrategy } from '@angular/common'; @Injectable() export class appService { private authUrl!: string; private getDashboardsUrl!: string; private header!: HttpHeaders; constructor(private http: HttpClient) { } public GetDashboards(getDashboardsUrl: string) { this.header = new HttpHeaders(); this.header = this.header.append('Access-Control-Allow-Origin', '*'); this.header = this.header.append('Authorization', 'bearer ' + "token"); return this.http.get(getDashboardsUrl, { headers: this.header }).pipe(res => { return <any>res; }); } public GetEmbedConfig(getDashboardsUrl: string) { return this.http.get(getDashboardsUrl, { }).pipe(res => { return <any>res; }); } } -
Open the folder
ClientApp\src\appand create a new file calledapp.tsand include the following code.export class Item { Name!: string; Description!: string; Id!: string; Version!: string; IsPublic!: boolean; ItemLocation!: string; CategoryName!: string; } -
Open the folder
ClientApp\src\appand create a new file calleddashboard.service.tsand including the following code. These properties are used to get and set the value of this property.import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class DashboardService { public embedConfig: any; getEmbedConfig(): any { return this.embedConfig; } setEmbedConfig(embedConfig: any): void { this.embedConfig = embedConfig; } } -
Open the
assetsfolder and create asubfoldernamedcss. Within thecssfolder, create a new file calledsite.cssand place the provided code inside itbody html { width: 100%; height: 100%; } html, body,app-root { width: 100%; height: 100%; margin: 0; font-family: Roboto; font-size: 13px;} ul { list-style-type: none; padding-left: 0; } .tab { padding-top: 2px; padding-bottom: 18px; cursor: pointer } .active { background-color: burlywood; } .e-dbrd-blueWaitingIndcator { -webkit-animation: rotate 2s linear infinite; animation: rotate 2s linear infinite; height: 54px; width: 54px; top: 50%; left: 50%; position: relative; } .e-waiting { position: fixed; display: block; margin: 0px auto; width: 54px; height: 54px; zoom: 0.5; margin-left: 55px;} #container { width: 13%; float: left; height: 100%; float: left; background: #f4f4f4; height: 100%; box-shadow: 2px 0 4px 0 rgba(0, 0, 0, .12); overflow: auto; overflow-x: hidden; } #grid-title { font-size: 17px; border-bottom: 1px solid #333; padding: 15px;} #panel { width: 100%; float: left; background: #f4f4f4; overflow: auto;} #dashboard { width: 100%; float: left; height: 100%; display: block; } .dashboard-item { padding: 10px; border-bottom: 1px solid #ccc; cursor: pointer; } #viewer-section { width: 100%; height: 100%; float: left; } #viewer-header { padding: 10px; display: block; float: left; width: 100%; } #create-dashboard { float: right; margin-right: 20px; background: #0565ff; border: 0; border-radius: 4px; color: #fff;cursor: pointer; display: inline-block;font-size: 12px; font-weight: 600;height: 28px;line-height: 28px; min-width: 90px; outline: none; text-align: center;border: 1px solid #0450cc; } #edit-dashboard { float: right; background: #fff; margin-right: 20px; border: 0; border-radius: 4px; color: #333; cursor: pointer; display: inline-block; font-size: 12px; font-weight: 600; height: 28px; line-height: 28px; min-width: 90px; outline: none; text-align: center; border: 1px solid #b3b3b3; } #dashboardDesigner{ height: 900px; border: 2px solid #333; } .dashboard_container { height: 775px !important; width: 1685px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; margin-bottom: 0px !important;} .e-waitpopup-pane { display: none; } -
To install all dependent packages, use the following command
npm install. -
Run the ASP.NET core and angular applications using the
dotnet runcommand.