Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Get certified in Microsoft Fabric—for free! For a limited time, get a free DP-600 exam voucher to use by the end of 2024. Register now

Reply
cch1
Frequent Visitor

dashboard tileclicked - how to get tile's external link url?

For tiles on a dashboard with the external link defined, where can I find that url from the tileclicked event?

 

When I look at the event.detail in the following code, there's no reference to a external link URL

 

 

dashboard.on("tileClicked", function (event) {

 alert(JSON.stringfy(event.detail));

});

1 ACCEPTED SOLUTION
Eric_Zhang
Microsoft Employee
Microsoft Employee

@cch1

I just tested and found that only when the "Set cutom link" is checked then the reponse JSON would contains the filed "targetUrl", otherwise the field "targetUrl" is missing instead of showing blank.

 

Capture.PNG

View solution in original post

8 REPLIES 8
Eric_Zhang
Microsoft Employee
Microsoft Employee


@cch1 wrote:

For tiles on a dashboard with the external link defined, where can I find that url from the tileclicked event?

 

When I look at the event.detail in the following code, there's no reference to a external link URL

 

 

dashboard.on("tileClicked", function (event) {

 alert(JSON.stringfy(event.detail));

});


@cch1

If you mean the external link set in Power BI service, AFAIK, it is not possible to get it. As when clicking on the tiles of an embedded dashboard, it doesn't navigate any page as the clicking on tiles does in Power BI Service. Per my understanding, it is dependent from the Power BI service.

Capture.PNG

 

However you could get the target url of a tile with Power BI REST API, see Get Tiles.

Capture.PNG

Hi Eric,

 

The GetTiles link you referred me to (https://msdn.microsoft.com/en-us/library/mt465741.aspx?f=255&MSPPError=-2147217396)  doesn't have an targetUrl field in its response.

 

it's different than the results you're showing.  What is the correct method to use to get a dashboard tile's

 

I'm referring to your original response:

true.pngtrue.png

 

 

Eric_Zhang
Microsoft Employee
Microsoft Employee

@cch1

I just tested and found that only when the "Set cutom link" is checked then the reponse JSON would contains the filed "targetUrl", otherwise the field "targetUrl" is missing instead of showing blank.

 

Capture.PNG

Hi Eric,

 

Thanks for the reply.  

 

Is the get tiles operation possible wher the app was registered as a native app (registered on dev.powerbi.com/apps)?    From the sample code, to call the gettiles(), the app requires an access token which is dependednt on a client secret, which is not provided when the app is registered as a native app (in powerbi sample terminology - app owns the data vs the user owns the data).

 

We're trying to embed a dashboard where the user does NOT have to login as a powerbi user  (the powerbi username/password is hardcoded into the application).

cch1
Frequent Visitor

Hi Eric,

 

Based on your suggestion, I tried to access the PowerBI REST APIs; however, when I try to access it, I receive a 403 Forbidden error.

 

 

Sample Code:

 

string Username = ConfigurationManager.AppSettings["pbiUsername"];

string Password = ConfigurationManager.AppSettings["pbiPassword"];

string AuthorityUrl = ConfigurationManager.AppSettings["authorityUrl"];

string ResourceUrl = ConfigurationManager.AppSettings["resourceUrl"];

string ClientId = ConfigurationManager.AppSettings["clientId"];

string ApiUrl = ConfigurationManager.AppSettings["apiUrl"];

string GroupId = ConfigurationManager.AppSettings["groupId"];

 

 

var error = GetWebConfigErrors(ClientId, GroupId, Username, Password);

if (error != null)

{

   return new ReportListingViewModel()

      {

              ErrorMessage = error

       };

}

 

// Create a user password cradentials.

var credential = new UserPasswordCredential(Username, Password);

// Authenticate using created credentials

var authenticationContext = new AuthenticationContext(AuthorityUrl);

var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ClientId, credential);

if (authenticationResult == null)

{

 

 return new ReportListingViewModel()

 {

    ErrorMessage = "Authentication Failed."

  };

}

var tokenCredentials = new TokenCredentials(authenticationResult.AccessToken, "Bearer");

 

// Create a Power BI Client object. It will be used to call Power BI APIs.

using (var client = new PowerBIClient(new Uri(ApiUrl), tokenCredentials))

{

// Get a list of dashboards.

var dashboards = await client.Dashboards.GetDashboardsInGroupAsync(GroupId);

 

// Get the first report in the group.

Dashboard dashboard = null;

foreach (var d in dashboards.Value)

{

  if (d.DisplayName.ToUpper().Trim() == _GetDashboardByUserName())

    {

      dashboard = d;

   var oTiles = await client.Dashboards.GetTilesInGroupAsync(GroupId, d.Id);

   foreach (var t in oTiles.Value)

   {

     string s = t.EmbedData;    // **** Note the EmbedData is always NULL, even for those tiles with external link defined.

   }

   break;

   }

}

 

if (dashboard == null)

{

  logger.Error("_GetDashboardData: Group has no dashboards.");

  return new ReportListingViewModel()

    {

    ErrorMessage = "Group has no dashboards."

     };

}

 

// Generate Embed Token.

var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");

var tokenResponse = await client.Dashboards.GenerateTokenInGroupAsync(GroupId, dashboard.Id, generateTokenRequestParameters);

if (tokenResponse == null)

{

   return new ReportListingViewModel()

     {

    ErrorMessage = "Failed to generate embed token."

     };

}

 

//Configure tiles request

System.Net.WebRequest request = System.Net.WebRequest.Create(

String.Format("{0}Dashboards/{1}/Tiles",

@"https://api.powerbi.com/v1.0/myorg/",

@"<My dashboard ID>")) as System.Net.HttpWebRequest;

request.Method = "GET";

request.ContentLength = 0;

request.Headers.Add("Authorization", String.Format("Bearer {0}", tokenResponse.Token));

//  ****  I receive a 403 error exception when I call request.GetResponse()

using (var response = request.GetResponse() as System.Net.HttpWebResponse)

{

//Get reader from response stream

using (var reader = new System.IO.StreamReader(response.GetResponseStream()))

{

  //Deserialize JSON string

  PBITiles tiles = JsonConvert.DeserializeObject<PBITiles>(reader.ReadToEnd());

  //Sample assumes at least one Dashboard with one Tile.

 

  if (tiles.value.Length > 0)

   {

   string r = tiles.value[0].embedUrl;

   }

  }

}

// Generate Embed Configuration.

var embedConfig = new ReportListingViewModel()

{

   EmbedToken = tokenResponse,

   EmbedUrl = dashboard.EmbedUrl,

   Id = dashboard.Id,

};

return embedConfig;

Eric_Zhang
Microsoft Employee
Microsoft Employee

@cch1

Have you picked up all permission for the registered app and grant permissions(how?) to the account used to generate accesstoken? I have no problem calling the Get Tiles with a native app. For testing purpose, you could try to get an accesstoken as below.

 

static string getAccessTokenSilently()
        {

            HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp("https://login.windows.net/common/oauth2/token");
            //POST web request to create a datasource.
            request.KeepAlive = true;
            request.Method = "POST";
            request.ContentLength = 0;
            request.ContentType = "application/x-www-form-urlencoded";

            //Add token to the request header
            request.Headers.Add("Authorization", String.Format("Bearer {0}", token));

            NameValueCollection parsedQueryString = HttpUtility.ParseQueryString(String.Empty);
            parsedQueryString.Add("client_id", {clientID});
            parsedQueryString.Add("grant_type", "password");
            parsedQueryString.Add("resource", "https://analysis.windows.net/powerbi/api");
            parsedQueryString.Add("username", {yourusername});
            parsedQueryString.Add("password", {yourpassword});
            string postdata = parsedQueryString.ToString();


            //POST web request
            byte[] dataByteArray = System.Text.Encoding.ASCII.GetBytes(postdata); ;
            request.ContentLength = dataByteArray.Length;

            //Write JSON byte[] into a Stream
            using (Stream writer = request.GetRequestStream())
            {
                writer.Write(dataByteArray, 0, dataByteArray.Length);
                var response = (HttpWebResponse)request.GetResponse();
                var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
                dynamic responseJson = JsonConvert.DeserializeObject<dynamic>(responseString);
                return responseJson["access_token"];
            }


        }

 

Hi Eric,

 

Thanks for the last code snippet, I'm able to connect to the tiles via (https://api.powerbi.com/v1.0/myorg/groups/{group_id}/dashboards/{dashboard_id}/tiles); however, the response that's returned is the following as per the get tiles documentation.     There's no action or targetUrl element as per your original reply.

 

Where can I find the tile's targetUrl?  Can you provide sample code that retrieves this value?

 

{  
  "@odata.context":"https://api.powerbi.com/v1.0/myorg/$metadata#tiles","value":  
  [  
    {  
      "id":"{tile_guid}",  
      "title":"tile_title",  
      "embedUrl":"https://api.powerbi.com/embed?dashboardId={dashboard_id}&tileId={title_id}"  
    }  
  ]  
}
cch1
Frequent Visitor

Hi Eric,

 

From my previous post, this is the based I'm currently using:

                string Username = ConfigurationManager.AppSettings["pbiUsername"];
                string Password = ConfigurationManager.AppSettings["pbiPassword"];
                string AuthorityUrl = ConfigurationManager.AppSettings["authorityUrl"];
                string ResourceUrl = ConfigurationManager.AppSettings["resourceUrl"];
                string ClientId = ConfigurationManager.AppSettings["clientId"];
                string ApiUrl = ConfigurationManager.AppSettings["apiUrl"];
                string GroupId = ConfigurationManager.AppSettings["groupId"];

                var error = GetWebConfigErrors(ClientId, GroupId, Username, Password);
                if (error != null)
                {
                  return new ReportListingViewModel()
                    {
                        ErrorMessage = error
                    };
                }

                // Create a user password cradentials.
                var credential = new UserPasswordCredential(Username, Password);

                // Authenticate using created credentials
                var authenticationContext = new AuthenticationContext(AuthorityUrl);
                var authenticationResult = await authenticationContext.AcquireTokenAsync(ResourceUrl, ClientId, credential);

                if (authenticationResult == null)
                {

                    return new ReportListingViewModel()
                    {
                        ErrorMessage = "Authentication Failed."
                    };
                }

                var tokenCredentials = new TokenCredentials(authenticationResult.AccessToken, "Bearer");
                
                // Create a Power BI Client object. It will be used to call Power BI APIs.
                using (var client = new PowerBIClient(new Uri(ApiUrl), tokenCredentials))
                {
                    // Get a list of dashboards.
                    var dashboards = await client.Dashboards.GetDashboardsInGroupAsync(GroupId);

                    
                    // Get the first report in the group.
                    Dashboard dashboard = null; 

                    foreach (var d in dashboards.Value)
                    {
                        if (d.DisplayName.ToUpper().Trim() == _GetDashboardByUserName())
                       {
                            dashboard = d;

                            break;
                        }
                    }

                    if (dashboard == null)
                    {
                        
                        return new ReportListingViewModel()
                        {
                            ErrorMessage = "Group has no dashboards."
                        };
                    }

                    // Generate Embed Token.
                    var generateTokenRequestParameters = new GenerateTokenRequest(accessLevel: "view");
                    var tokenResponse = await client.Dashboards.GenerateTokenInGroupAsync(GroupId, dashboard.Id, generateTokenRequestParameters);

                    if (tokenResponse == null)
                    {
                        
                        return new ReportListingViewModel()
                        {
                            ErrorMessage = "Failed to generate embed token."
                        };
                    }

                        HttpWebRequest request = System.Net.HttpWebRequest.CreateHttp("https://login.windows.net/common/oauth2/token");
                        //POST web request to create a datasource.
                        request.KeepAlive = true;
                        request.Method = "POST";
                        request.ContentLength = 0;
                        request.ContentType = "application/x-www-form-urlencoded";

                        //Add token to the request header
                        request.Headers.Add("Authorization", String.Format("Bearer {0}", authenticationResult.AccessToken));

                        NameValueCollection parsedQueryString = HttpUtility.ParseQueryString(String.Empty);
                        parsedQueryString.Add("client_id", ClientId);
                        parsedQueryString.Add("grant_type", "password");
                        parsedQueryString.Add("resource", @"https://analysis.windows.net/powerbi/api");
                        parsedQueryString.Add("username", Username);
                        parsedQueryString.Add("password", Password);
                        string postdata = parsedQueryString.ToString();


                        //POST web request
                        byte[] dataByteArray = System.Text.Encoding.ASCII.GetBytes(postdata); ;
                        request.ContentLength = dataByteArray.Length;

                        //Write JSON byte[] into a Stream
                        using (Stream writer = request.GetRequestStream())
                        {
                            writer.Write(dataByteArray, 0, dataByteArray.Length);
                            var response = (HttpWebResponse)request.GetResponse();
                            var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
                            dynamic responseJson = JsonConvert.DeserializeObject<dynamic>(responseString);
                            

                            //Configure tiles request
                            System.Net.WebRequest req = System.Net.WebRequest.Create(
                                String.Format("{0}groups/{1}/Dashboards/{2}/Tiles",
                                @"https://api.powerbi.com/v1.0/myorg/",
                                GroupId,
                                @"<MY DASHBOARD ID>")) as System.Net.HttpWebRequest;

                            req.Method = "GET";
                            req.ContentLength = 0;
                            req.Headers.Add("Authorization", String.Format("Bearer {0}", responseJson["access_token"]));

                            //Get tiles response from request.GetResponse()
                            using (var resp = req.GetResponse() as System.Net.HttpWebResponse)
                            {
                                //Get reader from response stream
                                using (var reader = new System.IO.StreamReader(resp.GetResponseStream()))
                                {
                                    //Deserialize JSON string
                                    PBITiles tiles = JsonConvert.DeserializeObject<PBITiles>(reader.ReadToEnd());

                                    //Sample assumes at least one Dashboard with one Tile.
                                    //You could write an app that lists all tiles in a dashboard
                                    if (tiles.value.Length > 0)
                                    {
                                        string r = tiles.value[0].embedUrl;
                                    }
                                }
                            }
                    }

Helpful resources

Announcements
November Carousel

Fabric Community Update - November 2024

Find out what's new and trending in the Fabric Community.

Live Sessions with Fabric DB

Be one of the first to start using Fabric Databases

Starting December 3, join live sessions with database experts and the Fabric product team to learn just how easy it is to get started.

Las Vegas 2025

Join us at the Microsoft Fabric Community Conference

March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early Bird pricing ends December 9th.

Nov PBI Update Carousel

Power BI Monthly Update - November 2024

Check out the November 2024 Power BI update to learn about new features.