SharePoint Images Powered Up In PowerApps

Cross-posting – originally published on My Consult

I recently came across upon on a publication on National Geographic’s website pertaining to Albert Einstein’s theory of relativity. As I read through that article, I could not help but find myself on occasion laughing as I read some of the commentary in that publication, the most amusing of which to me at least were, to quote:

  • …the thing is, if you pick up a copy of Einstein’s original paper on relativity from 1905, it’s a straightforward read. His text is plain and clear, and his equations are mostly just algebra—nothing that would bother a typical high-schooler.
  • It wasn’t easyEinstein tried every solution he could think of, and nothing worked. Almost out of desperation, he began to consider a notion that was simple but radical.”
  • …he produced easily the most famous equation ever written: E = mc2.

Remarkably though, Albert Einstein had no special talents, he was only passionately curious. Perhaps put another way, that was how he at least described himself! 

Albert Einstein was most certainly a genius, and it would be wishful thinking on my part to be able to write a blog on a topic such as this one that other’s might consider to a be “straightforward read”, and equally so if the solution described within this blog was as simple as the equation “E = mc2”.

With that said though, I shall nonetheless endeavor to keep the complexity of solution as is detailed below as relatively simple as it can possibly can be, given that I most certainly do not possess talents anywhere close to the likes of Albert Einstein 😂.

Introduction

Two years ago, I learnt of a couple of new products Microsoft were releasing as part of the next generation modern workspace evolution of the Office 365 platform. Those two products were PowerApps and Flow. PowerApps, framed as a service that empowers anyone to create applications for their organizations, whether those app makers could potentially be non-technical business users, experienced application developers, or even perhaps school-going children who quite possibly may never have had any experience whatsoever in creating any sort of applications before.

Being a v1 product targeting such a broad base and skillset of potential users, naturally there has been a huge demand for additional new or enhanced features and capabilities within the product, as the adoption of the product within organizations has exponentially grown in an exceeding short period of time. That said it is quite remarkable the pace at which an extensive number of new features and functionality have been rolled out in rapid release cycles, such as to address a significant number of suggestions put forward by the ever-growing user base for both PowerApps and Flow.

It is not all that surprising that following the announcement of the general availability of PowerApps, a number of the post-v1 features and functionality that Microsoft anticipated would be introduced as native functionality within these products soon thereafter, subsequently transpired to be far more complex to implement that had been originally been envisaged at least. 

By example, the solution as described in this blog, would not have been possible to conceive in February 2018. This is nonetheless completely understandable given the rapid evolution of the underlying platform, Office 365, upon which PowerApps and Flow have now become core components thereof (i.e. Office 365 Tier-1 services equal in statue to the likes of SharePoint, OneDrive, Mail, Teams etc.).

As these two products stand today however, the number of “Must-Have” feature requests, as put forward by the PowerUsers community, is thankfully now far lower then it was when compared to perhaps say one year ago. Of these, the top two “Must-Have” feature requests for both PowerApps and Flow for that matter that continue to stand out most often “in my opinion at least” certainty appear to be:

The ability to Share PowerApps apps with External Users

I personally do not include the ability to share PowerApps with external users as one of those “Must-Have” feature requests, simply because Office 365 was never intended to be an Internet website hosting platform. Certain services part of the Office 365 platform has been enriched to include additional functionality over time that have enabled very specific point external collaboration and sharing features for organizations using Office 365. Each of these point solutions have equally required careful planning and due consideration, such that organizations have likewise gained confidence in the platform that their content and information is protected, and that the necessary checks and balances have always been done before any of those external point sharing and collaboration features and capabilities where introduced and rolled out to the consumer market.

Put another way, sharing for example a SharePoint Online site externally is one thing, whilst sharing a SharePoint online site externally that includes an imbedded PowerApps webpart that could quite possible include Connections to 10+ internal organization backend systems is altogether different. Put another way, as was noted a few paragraphs above, both PowerApps and Flow were introduced to the Office 365 ecosystem whilst that ecosystem itself has been undergoing evolutionary changes. Accordingly the roadmap for potentially introducing this specific user request would most certainly always have had a dependency on the Azure Active Directory (Azure AD) business-to-business (B2B) collaboration capabilities that are only now being incorporated into the Microsoft cloud platform offerings suite of services.

Enriched Integration with SharePoint Online

One of the more common use case scenarios for app makers leveraging PowerApps would quite possibly include consuming SharePoint Online back-end data source connections within those apps.

The PowerUsers community have made several outstanding contributions to the broader user base of these products to provide workarounds for many of the more challenging and exceedingly difficult unexpected obstacles that have presented themselves since the general availability release of both PowerApps and Flow to the consumer market within Office 365.

I am sure however many of the people reading this blog know all this of course, so let’s get on then and focus on the primary intent of this blog.

“Why haven’t you already, damnit…?” 😊

Historical Challenges of Displaying Content from SharePoint

So what then is this blog all about and is it worth your time reading, you may well ask?

Quite possibly it is, especially should you have ever tried to do any of the following within your PowerApps applications:

  • Display images stored in SharePoint Online within your apps.
  • Display Microsoft Word documents, Microsoft PowerPoint presentations or pure HTML content stored in SharePoint libraries which have been converted automatically on the fly into PDF documents and rendered as such within PowerApps.
  • Display Microsoft Word documents, Microsoft PowerPoint presentations, Adobe PDF documents or pure HTML content stored in SharePoint libraries which have been converted on the fly to images and rendered as such within PowerApps (albeit the first page only of any type of documents other HTML content – at least to the extent I have been able to test thus far).

The requirement for apps makers to render images stored in SharePoint within their PowerApps applications is certainly nothing new. In fact, app makers have been requesting this functionality for near on 2 years, as have been submitted on Microsoft’s PowerUsers website.

Sadly, I cannot provide the answers to all these highly sought-after feature requirements as have been requested by many users within the PowerUsers community – at least not within a single blog that is 😅.

This blog is the thus accordingly the first of a series of blogs which shall follow in due course.

As the title of this blog suggests, the focus of the content as is detailed below pertains to the rendering of images natively within PowerApps, the back-end data source where those images have been stored being SharePoint Online.

The Organization That Inspired This Solution

In July 2017 I was presented with an opportunity to join a team of like-minded individuals and participate in Microsoft’s annual Hackathon, a three-day, global event for employees. Our team comprised of 16 exceptionally talented employees from five countries spread across 3 continents including Asia, Africa and North America. Each member of our team had equally been touched upon hearing the story of Yuwa, a nonprofit soccer and school academy for girls in Jharkhand, India. We all voluntarily came together upon hearing the story of these young girls such as to help Yuwa by contributing our collective skills and time in whichever we could during the three days of the Hackathon event.

Yuwa, which means “youth” in Hindi, works specifically with girls from impoverished families in rural Jharkhand, India—a place where girls are at risk of child marriage and human trafficking. It is a program that uses team sports and education to build character, confidence, and courage. Yuwa was founded in 2009 when American Franz Gastler moved to Jharkhand, having grown up in Minnesota. 
Using football to educate girls: Franz Gastler & Kusum Kumari at TEDxGateway 2013
http://www.tedxgateway.com/portfolio/franz-gastler-2

Franz and Yuwa have won awards from Nike Gamechangers, Yahoo, Barclays, Times Now, NDTV and Ashoka Changemakers, and have been featured in countless media including BBC, Bloomberg Businessweek, Times of India, Hindustan Times, Outlook, The Hindu, Indian Express, Mint, CNN-IBN, Tehelka, People Magazine and others.

5 out of 10 girls in Jharkhand drop out of school and become child brides. But not these girls. When girls know their worth, they’re limitless.

Subsequent to the incredible accomplishments our team were able to achieve during that Hackathon within just 3 days, a few months later I reached a personal goal and milestone in my own life whereupon I completed 10 years of service as an employee of Microsoft at the end of September 2017.

A few people I knew had been asking me some months earlier what my next personal goal in my life was thereafter, and at that time at least the only response I could come up with jokingly was “I’d like to change the world of course 😊”

However, as things transpired and having been incredibly moved and inspired by something I most certainly never expected to have even been a part of at that time, I personally found my own life changing as the inspiration I myself had drawn in working alongside Yuwa during those few days in July 2017 grew within me.

Please Support the Amazing Organization that Inspired this Solution

In October 2017 I ventured out to explore new opportunities to further my own personal aspirations and other lifetime goals I myself had in mind. I was nonetheless very much drawn to Yuwa and the personal commitment I had made to their organization to nonetheless endeavor to offer as much of my own personal time and skills (philanthropy efforts) as I possibly could, because the order of magnitude that this organization had in fact inspired me such as to realize that so many of us can actually make a measurable difference that can and will help shape the lives, the dreams and the aspirations of these young girls in India, through the work that Yuwa are doing.

I have personally spent a substantial amount of my own time creating an app leveraging PowerApps that enables Yuwa to track attendance for both school class sessions as well as team football practices and is one of several components that together have culminated in a far wider overall solution that is already making a difference to Yuwa and enabling them to achieve far larger goals, supporting their own mission within this improvised community.

Earlier this year before the development of the overall solution developed for Yuwa had been completed, I was devastated when I learnt of one of the girls in the program had sadly dropped out. When you personally witness something as devastating as this actually happen, you begin to appreciate how important it is for Yuwa to be able to quickly pick up changes in terms of attendance for girls within the program, such that there is still an opportunity to bring those girls back into the program before it is too late.

This app and accompanying additional components of the overall solution (such as PowerBI reports), enable Yuwa to intervene that much quicker because they absolutely have to.

I have had the fortune of working alongside some of the most wonderful people I have ever had the opportunity to work with, yet never met 😋, including:

  • Franz Gastler and Shyam Prasad ( Yuwa )
  • Shaurabh ThapaDivika Mittal and Thamis Mendez  ( Microsoft )
  • Joey Posthumus ( MyConsult )

No one is immune to abuse, nor to the shame and hopelessness that come with it
Brendan Fraser’s #MeToo Story – MEL Magazine

Anyone’s life can be shattered apart in an instant. Child, adult, female, male.

Were it not for Yuwa this blog would likely never have been published. Should this story, that so inspired me to genuinely believe that anything is actually possible, even when the odds are monumentally stacked up against you, equally inspire anyone who may perhaps read this blog, irrespective of whether or not they are hopefully appreciative that this solution has equally been shared in the hope that in some small way, perhaps there is still more even I can do for these girls and this incredible organization that has given hopes and dreams and even life itself to these amazing children.

Whilst the monumental efforts of one individual can make a real, albeit small, difference to help these young girls realize some of their dreams and aspirations within their own lives, in order to make a monumental impact of profound proportions, all that is really required is the smallest possible contribution from each person that is genuinely touched and inspired upon hearing their story.

Please make a small donation to Yuwa, if you can.

Demo of the Solution

Before delving further into the detail with regards to how the solution as described in this blog was developed, I have no doubt by now anyone who has managed to get this far into this blog would be far more interested in seeing a demo of solution in action before deciding whether their time thus far has been well spent 🧐.

As such, for this blog I have created two PowerApps applications. One app targeting mobile users and the other app designed for desktop / workstation (web browser) users. Both apps depict similar functionality, albeit that the mobile app displays images somewhat lower in resolution (thus smaller images in size), as would be appropriate for such users – the ‘default’ behaviour within that app at least (albeit fully adjustable at runtime).

Equally both demos were recorded at a time-lapse video speed of x1.5 on a mobile device, not for purposes of in any way creating a perception of exaggerated superior performance whilst rendering images within the apps, only such that the demo video were not unnecessarily too long overall (such that interest in the demos might otherwise perhaps wain).

Furthermore, the intent of the demo videos is equally to intentionally rapidly navigate through the photo galleries in each of the apps, whilst clicking on random images without any pauses such that the demos are reflective of the genuine performance in terms rendering different quality resolution images / thumbnail images of the exceptionally large original versions of many of those images, as are been stored in a SharePoint Online Site Assets library.

Desktop Version Demo
Mobile Version Demo

Platforms and Services Leveraged

This solution is based upon entirely OOB functionality available today within the Office 365 platform. There is no requirement for any components of the solutions to be deployed or configured in Azure (for example). 

Furthermore no “special” permissions are required to implement this solution either, such as an Office 365 Global Admin or even that of a SharePoint site owner for that matter.

Office 365 Services (Apps) Consumed

  • PowerApps
  • SharePoint Online
  • Flow

Premium Connectors / Third-Party Applications Required

  • N/A

Complexity to implement this Solution

The complexity of any apps you may choose to build using PowerApps, whereupon you might potentially leverage this solution, is of course entirely dependent on your own requirements for each of the apps you create.

In terms of the solution as is described in this blog however, if one were to extrapolate the specific lines of “code” you may have to modify, excluding any other code you can otherwise simply copy and paste, off the top of my head I would approximate that to be in the region of around 5 lines of code or so.

Unfortunately I couldn’t quite achieve something as simple as “E = mc2” 😂.

And Now… The Solution

Edit: December 2018

With v2.0 of the Microsoft Graph APIs, by and large the reasons for not leveraging the said APIs as were originally detailed below have been addressed. Furthermore leveraging the Graph APIs to in effect produce the same desired functionality as is articulated in this blog is now considered a Microsoft recommended (aka preferred) approach, and thus supersedes the technique leveraging the SharePoint RenderListDataAsStream pattern as is described in this blog at least.

I accordingly decided to rework the solution detailed below to instead leverage the Graph APIs and have subsequently posted new blogs describing how I updated the demo apps depicted in this blog, and equally share one of the updated demo PowerApps and new Flow. Should you be following this blog, this might be a good time to switch to the later blogs in the series 😉.

Leveraging Graph APIs in PowerApps & Flow – Photos
Leveraging Graph APIs in PowerApps & Flow – PDFs

The solution as described in this blog to render small thumbnail images stored in SharePoint for app was an important requirement for Yuwa and thus a vital feature of the PowerApps application developed for their school. The ability to display highly optimized images of each student as many of the girls in the school have identical names and surnames.

Being in one of the most impoverished parts of India, it was equally important to ensure that the photos displayed within the app were optimized and rendered as efficiently as possible. As you can well imagine, no teacher or coach in such a rural and impoverished part of the world would want to download 10 Mb+ of data (photos) simply to mark attendance for one day for their class or football session.

Using the same solution as is described it this blog, their teachers and coaches are now able to mark attendance for their class or team, whilst equally rendering tiny thumbnail images that are automatically generated on the fly for each student in their class or team.

On “AVERAGE” these thumbnail renditions of each photo are 1500+ times smaller than the original photo stored in SharePoint is. Irrespective of how large the original photo is, the thumbnail renditions of each photo that are automatically generated within this PowerApps application are consistently between 3-6Kb in size.

Per the demo videos in this blog, this level of optimization is equally true of original photos stored in SharePoint ranging between 20 MB – 50 MB in size, as it is true of original photos ranging from 1 MB – 20 MB in size. The only exception being PNG files, albeit even those are nonetheless still rendered as tiny thumbnail images, and significantly smaller than the original photos as are stored in SharePoint.

SharePoint’s relatively new RenderListDataAsStream REST API to the rescue!!!

The best documentation I eventually found on this API was on the Microsoft Docs website.

The SharePoint RenderListDataAsStream REST API does exactly what is the name suggests it does – i.e. it returns list item data stored in SharePoint as stream.

This includes functionality such as:

  • Lookup columns
  • Managed Metadata columns
  • Conversion of Microsoft Word documents to PDFs on the fly.
  • The URL to render images from SharePoint in any client app of your choice (including PowerApps naturally) at a highly optimized, completely dynamic and entirely flexible resolution of your choice, definable at run-time, leveraging the AMS Transform REST API, inclusive of the necessary access token that is required for client apps to consume that service (the access token being valid for 3 hours).
  • Potentially stream video stored in SharePoint…

With that however all said, equally worth noting is the associated credit where credit is due. Were it not for some amazing work I came across as was coded by Pawe Hawrylak and published on GitHub, without which it most certainly would have been significantly more challenging to figure out the solution I have, as is detailed below.

Rather than to write a novel in a no doubt vain attempt to “enlighten” anyone reading this blog wrt exactly what that code Pawe shared does, and how I was subsequently thereafter able to translate that code into something that could be used within a Flow, the rest of this blog will thus only focus on how the equivalent solution can be represented and function accordingly leveraging Flow instead!

Create the Flow

https://flow.microsoft.com

In this demonstration, I have started off with a new Flow and named the Flow “PowerApps – SPO Images”.

Step 1 – Add Trigger

The first step in the Flow is to add the “PowerApps – PowerApps” trigger to instantiate the Flow (i.e. from PowerApps).

Step 2 – Create Variable “Body”

Variable: Initialize variable

Add an action: “Variables – Initialize variable

Initialize variable - Body

For the Body variable, we are going to use some good old CAML code and enter that into the Value property.

{
    "parameters": {
        "RenderOptions": 4103,
        "ViewXml": "<View Scope=\"RecursiveAll\"><Query><Where><Eq><FieldRef Name=\"ID\"/> /><Value Type=\"Number\">1</Value></Eq></Where></Query><ViewFields><FieldRef Name=\"ContentType\"/><FieldRef Name=\"DocIcon\"/><FieldRef Name=\"PreviewOnForm\" Explicit=\"TRUE\"/><FieldRef Name=\"ThumbnailOnForm\" Explicit=\"TRUE\"/></ViewFields><RowLimit Paged=\"TRUE\">1</RowLimit></View>"
    }
}

Step 3 – Send an HTTP request to SharePoint

SharePoint - HTTP

For the third step in our Flow, we are going to add a SharePoint HTTP action to call the SharePoint RenderListDataAsStream REST API.

In this step in the Flow can are going use the

SharePoint – Send an HTTP request to SharePoint” action to use the relatively new SharePoint RenderListDataAsStream API to do some magical stuff with.

  • Site Address: *
  • Method: select “Post
  • *Uri: “_api/web/lists/GetbyTitle(‘Site%20Assets’)/RenderListDataAsStream
  • Headers: Add an “Accept” header key with a corresponding value of “application/json;odata=nometadata
  • Body: Use the Body variable created in the previous step

For the Site Address URL, we are going use Dynamic content which will be passed from PowerApps.

At this point, you will need to Save the Flow and then Test it from the same page on the Flow website.

Run flow

As we are calling a SharePoint REST API, we will need to grant permission for the Flow to connect to your SharePoint site.

Note: Permissions granted here will be specific to each user running the app. In other words, if the user hasn’t been granted permission to view specific images in any given SharePoint site library, this Flow will equally respect the actual permissions in SPO that been granted to each user of the app. 

Enter the URL of your SPO site, e.g:
https://[tenant].sharepoint.com/sites/PowerApps
Following which, click the “Run flow” button.

Once the flow has completed, click the “See flow run activity” link.

On the flow Run History page, you should see that the flow Test Succeeded.

Then click the on the latest Flow run to see the outputs from the flow that will have accordingly been generated.

At this point you should be able to see that the 3 steps in your flow completed successfully, and at this stage you will need to click on the

Send an HTTP request to SharePoint

step in the flow to view the OUTPUTS generated from that specific action step.


Why not then simply use Microsoft Graph?

Edit: December 2018

As noted earlier, the reasons detailed at least in this blog for not leveraging the Graph APIs have by all accounts been put to bed with the new / upcoming v2.0 release of Graph APIs.

I have since reworked the original demo apps created for this blog, and equally posted new blogs wrt what Microsoft certain consider a recommended practice in preference to leveraging the RenderListDataAsStream approach as is showcased in this blog.

Leveraging Graph APIs in PowerApps & Flow – Photos
Leveraging Graph APIs in PowerApps & Flow – PDFs

With Microsoft Graph, you would first need to register an app with Azure AD, such that you can thereafter get an access token from the Azure AD v2.0 endpoint, after which you can then use to make authenticated requests to Microsoft Graph.
Reference: Authorization and sign-in for OneDrive in Microsoft Graph

The underlying problem with PowerApps in terms of making calls to any of the Graph API endpoints is that Microsoft Graph does not provide any way for you to pass an access token as a parameter to any REST URL endpoints.

Consequently, even if you were to call a Flow from PowerApps to obtain an access token, there is (currently at least) no way within PowerApps to subsequently make http calls to any of the Graph API REST endpoints as there is no way to perform HTTP GET queries from PowerApps, and additionally no way to specify your own custom Request Headers nor Request Body for that matter.

By way of example, whilst the following is possible using Flow, there is no way to run the equivalent code natively within a PowerApps app:
GET
https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id={client_id}&redirect_uri={redirect_uri}
Response
https://myapp.contoso.com/myapp/callback?code=AwABAAAAvPM
The code query string value is the authorization code you can thereafter redeem for a set of tokens that allow you to authenticate with various Office 365 APIs (such as Microsoft Graph).
POST
https://login.microsoftonline.com/common/oauth2/token
Request Headers
  Content-Type: application/x-www-form-urlencoded
Body
  client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}
  &code={code}&grant_type=authorization_code&resource={resource_id}
Response {JSON}
{
  “expires_in”: 3600,
  “access_token”:”EwCo…AA==”,
  “refresh_token”:”eyJh…9323″
}

Demo – Authenticated request to a Microsoft Graph API endpoint
GET
https://graph.microsoft.com/v1.0/users
Request Headers
   Authorization: Bearer {access_token}
   Accept: application/json

If all the above REST API calls were executed in the context of a single flow run, the final output would be a JSON string containing the collection of users defined in the tenant. The JSON output could then equally be Parsed within that same flow, and thereafter possibly returned to PowerApps in an array which could then be used as you like, in the same way you might consume any other data source for that matter.

Accordingly, for other possible use cases as they might relate to the consumption of numerous other Microsoft Graph API calls, this “pattern” may quite well suffice for your app-specific requirements. However, this pattern is far from ideal as it pertains to rendering images stored in SharePoint Online sites within a PowerApps solution.
Some of the possible complications with using this type of pattern to return data via a Flow leveraging the Microsoft Graph API in terms of the viability of using this approach to render images stored in SPO natively within a PowerApps app include:

Highly inefficient
By example, given the use case requirement as has been outlined in this blog, if your requirement was to display a gallery containing say 100 images stored in SharePoint Online within PowerApps, your options in terms of leveraging a Flow to return thumbnail images generated leveraging Microsoft Graph would in probability need to be implemented in one of two possible approaches:

Call the flow to once and retrieve all 100 thumbnail images in one single batch. This would likely result a substantial delay before users of the app could see any thumbnail images in that gallery control, depending on the volume of data being returned (e.g. 200 Kb vs. say 5 Mb)

Equally should the user choose to view a small subset of those images in the gallery, and the vast majority of the thumbnails would nonetheless have been downloaded for no practical reason.

Call the flow repeatedly for each individual image to be rendered, as a user browses through the images gallery, resulting in a substantial number of flow runs per app session.

Cumbersome to Code
Notwithstanding that there are most certainly numerous other use cases for leveraging Microsoft Graph using this pattern via a Flow, one also must consider the code required within PowerApps to subsequently cache thumbnail images within each PowerApps session, how much local storage may be required in order to cache those images for that session, whilst equally bearing in mind that the images cached in any single PowerApps session will only be “cacheable” for that specific PowerApps session.

If you could pass the access token in a http request to a Microsoft Graph REST API, how might it then look?
If Microsoft Graph API REST calls perhaps supported passing the authentication token as a query string parameter to the http request, such a http request to a Microsoft Graph API endpoint might look something along the lines of the following examples:
https://graph.microsoft.com/v1.0/users?access_token=EwCo……AA
https://graph.microsoft.com/v1.0/me/drive/root/children?$select=id,name&access_token=EwCo……AA

That said, even if this was possible using an http request to a Microsoft Graph API endpoint, you would nevertheless still require an access token to pass as a query string parameter to the Graph API http endpoint. To obtain an access token you would thus in any case require a flow to return the access token each time the PowerApps app was launched, and if necessary should the initial access token expire within a PowerApps session, call that Flow once again to obtain a new valid access token.

This is in essence no different to the technique as is detailed within this blog, whereby a flow is called each time the PowerApps app is launched which subsequently returns an access token to PowerApps. However as this relates to the solution as is detailed in this blog, the access token for the solution as is described is not for the purposes of authenticating Microsoft Graph API REST calls, it is instead passed as a query string parameter in an http request to the Media Services Transform API endpoint for authentication purposes. This is in fact the same API that is used natively within SharePoint Online when you view the vast majority of images in, by way of example, any Site Assets library.


Step 4 – Parse JSON Response

Picking up again on the flow where left off earlier, as detailed above, you will need to copy the entire Body value from the

Send an HTTP request to SharePoint

step in the flow, before we continue to add the next step to our flow.

For the fourth step in our Flow, we are going to “Add an action”
Data Operations – Parse JSON

In this step we are going to use the “Parse JSON” action to parse the JSON output data from the previous step in our flow (“Send an HTTP request to SharePoint”).

To parse the JSON output from our previous step, we first need to provide a JSON schema against which to parse that content. Flow can thankfully automatically generate that schema for us based upon the sample payload as we have copied from the OUTPUTS Body value per the previous step in the flow.

To do this, click on the Use sample payload to generate schema link as depicted below:

Paste the sample JSON payload as was copied from the OUTPUTS Body value per the previous step in the flow.

Having thus used the sample JSON payload to generate the schema, the Parse JSON step in your flow should henceforth look similar as to the corresponding screenshot depicted here.

Step 5 – Return values to PowerApps

For the fifth and final step in our Flow, we are going to return a single string back to PowerApps.

Accordingly, “Add an action” step as follows
PowerApps – Respond to PowerApps

Add a Text Output (thumbnailUrl).

Insert the code below for the value of the thumbnailUrl text output variable.

concat(replace(replace(replace(replace(replace(body('Parse_JSON')?['ListSchema']?['.thumbnailUrl'],'{.mediaBaseUrl}',body('Parse_JSON')?['ListSchema']?['.mediaBaseUrl']),'{.fileType}','jpg'),'{.callerStack}',body('Parse_JSON')?['ListSchema']?['.callerStack']),'{.spItemUrl}',concat(body('Parse_JSON')?['ListSchema']?['.driveUrl'],'/root:/','{filename}',':?version=Published&encodeFailures=1')),'{.driveAccessToken}',body('Parse_JSON')?['ListSchema']?['.driveAccessToken']),'&width={width}')

All boding well, that is it in terms of the five steps we require in our flow, and the corresponding code pertaining to each of those steps!

The only thing left to do from the Flow website at least, is to perform one final test run of the flow to validate that each step in the flow completes successfully as we expect it to…

Enter the URL of your SPO site, for example:
https://[tenant].sharepoint.com/sites/PowerApps

Once the flow has completed, click the “See flow run activity” link.

On the flow Run History page, you should see that the flow Test Succeeded.

Then click the on the latest Flow run to see the outputs from the flow that will have accordingly been generated (once again…).

At this point you should be able to see that the all 5 steps in your flow should hopefully have successfully completed as is depicted above.

All that is left to do now, is click on the “Respond to PowerApps

step in the flow to view the OUTPUTS generated from the final step in the flow we have created.

The “Body” OUTPUT will be a JSON string, with a “thumbnailurl name/value pair that will be returned to PowerApps as a string variable you can thereafter use within your app as you so desire.

Per the ILLUSTRATIVE EXAMPLE as is depicted above, the value of that thumbnailurl string variable should look along the lines of the following:

“https://[location]-mediap.svc.ms/transform/thumbnail?provider=spo&inputFormat=jpg&cs=fF***w&docid=https://[tenant].sharepoint.com/_api/v2.0/drives/b!M***Tr_PS*****qOWmPysKhroI_Em7G***jqcyL******ipD8Rb***m9u29/root:/{filename}:?version=Published&encodeFailures=1&access_token=ey*******Jub25l**0.ey**dW*iO?A**mVw***ChLTl**Et**ZDB******nlv**21LZ***zYnRp**dn*Z3pU***VBWT0&width={width}”

Of relevance from a PowerApps consumption perspective you will notice {placeholders} for two specific parameters to the Media Services Transform API call, namely {filename} and {width}.

Within PowerApps you can henceforth use the Substitute function to replace these {placeholder} parameters on demand as you so choose, providing you the ultimate solution in terms of both flexibility of the specific image(s) you would like to render in your app and equally at any resolution you may so desire.

In PowerApps any images rendered will be done so at the highest possible compression ratio imaginable of your original images as are stored in your SPO site, the extent to which by all means – please leave a comment on this blog with regards to your own personal findings…

In Closing

By now I am sure everyone who has read through this rather detailed write-up to this point at least is no doubt curious whether this Flow indeed does actually work, and if so, does the solution work as efficiently as you might hope it does….?

You too can also help make a difference to the lives of the beautiful young girls who go to Yuwa and help them build a new school where they can equally be inspired to achieve so much more, and help get, many other young girls into the same program.

If the solution to display images within PowerApps, as is described in this blog, is of particular value to you and / or your organization, please consider making a small (or large 😉) contribution to the organization whom inspired the person to figure out this solution, and this subsequent blog so that others too may perhaps benefit, and equally be inspired by Yuwa!

http://www.yuwa-india.org/donate
Brian Edwards
MCSM – Charter SharePoint

#MeToo

I personally attribute this blog in remembrance of my beloved brother, Craig Edwards, as well as my wonderful parents and family.

Craig sadly passed away following a long battle with brain cancer on the August 4th, 2012, the day before I started 3 weeks of the most grueling and intensive training imaginable for my Microsoft Certified Master – SharePoint certification.

Living the Moment: A True Story Paperback
by Léonie Edwards

8 thoughts on “SharePoint Images Powered Up In PowerApps”

  1. The source code for the demo apps showcased in this blog has been shared on GitHub:
    https://github.com/Office365Master/SharePoint-Images-Powered-Up-In-PowerApps

    That said, subsequent to this blog post v2.0 of the Graph APIs now support temporary authentication tokens to be passed to at least some of the Graph API REST URLs. Going forward this is now a recommended technique over the approach using the SharePoint RenderListDataAsStream REST API as was detailed in this particular blog. The same demo apps showcased in this blog have equally been updated to leverage the Graph APIs along with a new blog post is this series. Check it out if you haven’t already!
    https://masteroffice365.com/leveraging-graph-in-powerapps-and-flow/
    https://github.com/Office365Master/Leveraging-Graph-APIs-in-PowerApps-and-Flow

  2. Usually I do not read article on blogs, but I wish to say that this write-up very compelled me to check out and do so!
    Your writing style has been surprised me. Thanks, very great article.

  3. What i don’t understood is in reality how you are no longer actually much more smartly-favored than you may be right now.
    You are very intelligent. You realize therefore considerably with regards to this matter, made me in my opinion imagine it from so many varied angles.

    Its like men and women don’t seem to be fascinated except it’s something to
    do with Woman gaga! Your own stuffs great. All the time maintain it up!

Leave a Reply

Your email address will not be published. Required fields are marked *