Showing posts with label powerapps. Show all posts
Showing posts with label powerapps. Show all posts

Tuesday, April 23, 2019

Gotcha in Microsoft Flow when handling SharePoint list item attachments


I’ve written a couple of these, where I in PowerApps allow the user to upload attachments to a list item. This feature can typically be used to upload documents or photos from the end user.

While list attachments work fine they are often easier managed in a separate document library, or perhaps you want to perform some other action on them. And this is where Flow comes into the picture. When the item is saved in SharePoint associate a Flow which triggers on new items in the list.

What is important to note is that when list items with attachments are created, the item is first created, and then each attachment will be a subsequent operation. When this action is performed using a phone or tablet the attachment upload might take some time, and Flow might very well trigger before all the attachments are done uploading - the effect being that Flow will miss some of the attachments, and your business process can miss some important data.

Wednesday, March 20, 2019

A simple solution to implementing proper back functionality in PowerApps



When navigating between screens in PowerApps you use the Navigate function. There is also a Back function which takes you to the previous screen. The caveat with Back is that it doesn’t build a navigation history, but remember the previous screen only. This means that if you go from screen 5 to 4 using Back, then the next Back call will take you to 5 again, not screen 3.

Do I really need to think about this?

Thursday, February 28, 2019

PowerApps user filtering gotcha against SharePoint

image

PowerApps has for a long time supported filtering SharePoint data based on a person – the typically scenario in a PowerApps being that you want to fetch data rows based on the logged in user in PowerApps.

If you look at the post https://powerapps.microsoft.com/en-us/blog/powerapps-now-supports-working-with-more-than-256-items-in-sharepoint-lists/ they have a sample along the lines of:

Filter('Issues',AssignedTo.Email=User().Email)

Issues is a SharePoint list and AssignedTo is people field, containing the person an issue is assigned to.

The issue with this sample is that User.Email() actually returns thee user principle name (UPN), and not the e-mail address, and the value is also always in lower case. For most users this does not represent a problem, but for some it might. If your e-mail address is Foo.Bar@contoso.com, the UPN could be foo.bar@contoso.com, thus the filtering would fail as it’s case sensitive.

The solution is to filter on the Claims property for a person field in SharePoint instead of Email.

What I typically do is that in the application OnStart event I set a global variable where I prefix the UPN with the default claims prefix.

Set(CurrentUserClaim,Concatenate("i:0#.f|membership|",User().Email))

The filter command then turns into:

Filter('Issues',AssignedTo.Claims=CurrentUserClaim)

Happy PowerApp’ing!

Thursday, January 24, 2019

A no-nonsense solution to implement cascading dropdowns using PowerApps as a custom form in SharePoint

Search for “powerapps cascading dropdowns sharepoint” on the interwebs and you will find a bunch of ways to get this to work, but I dare to say that the solution I propose is by far the easiest and most elegant. And a big thank you to my colleague Thomas who helped along with this one.

My sample is super easy. I have three lists, Countries, Cities and Customers. Cities has a lookup to Countries, and Customers has a lookup to both Countries and Cities.

image

By default the input form looks like the image below, where all cities are shown regardless of the selected country. But this is easily fixed.

image

Monday, March 19, 2018

A workaround for saving hi-res photos from PowerApps to SharePoint

Saving photos or images from PowerApps to SharePoint is not easy, but there are workarounds using for example Flow to get this to work as I’ve written about previously. The caveat with this approach is that when using the camera control you won’t get full resolution on the images you take, but a scaled down version – and adding Flow to the mix increased complexity.

With the recent release of supporting attachments with SharePoint lists in PowerApps it’s now possible to get those high resolution photos into SharePoint. But, it’s not straight forward. Even though it’s possible you should think it through before going full on production with this.

Note: This post is written based on testing on iOS.

Uploading photos is a common ask when using PowerApps on mobile device. You might create a reporting application of sorts which supports adding photos as documentation. My first thought was to utilize the new attachment support, pick the camera as input and be done with it. Turns out I should stop believing in fairy tales when a feature is just released :). When tapping the “Attach file” link, you get a dialog to browse your iCloud Drive, not an option to tap into the camera. Which makes sense as you need an attachment filename. This means we cannot use the default add attachment functionality.

20180318_124151000_iOS

What I came up with was using the “Add picture” control with a custom collection, and then binding the forms attachment control value to this collection. You also need to reset the form after you modify the collection in order for the change to be picked up in the control (which is needed for it top be submitted). The reset has a timing issue, so I had to add a timer control which reset’s the form every 1 second. It’s all in a days works of duct tape.

Oh well.. let’s build the application, and you will see for yourself.

Friday, March 16, 2018

How to display images from a SharePoint library in PowerApps

[Update: As mentioned in the comments by Paul Culmsee, this only works in the web version of PowerApps - not on devices. To make it work on devices take a look at his posts for a proxy workaround]

A while back I wrote a post about how to save images from PowerApps to SharePoint via Flow. Today  I got a comment asking how you can show images sored in a SharePoint library in a PowerApp. Turns out it’s not hard at all.

I first created a new document library named “Images” in a SharePoint site and uploaded two images.

image

Within your PowerApp add a new data source, and manually type in the name to the library containing your files, in my case “Images” and hit “Connect”. The manual typing is the crux to make this work.

image

Next add a gallery to your app and bind it to the Images data source. For the Image control, change the binding to be ‘{Link}’ and you should see your images showing up in the gallery.

image

Happy PowerApping!

Sunday, August 27, 2017

Maybe the most useful Azure function ever! – Introducing a proper Swagger definition generator

This post relates to Azure functions written in C#, hosted as a Function App – and maybe the title is a tiny bit clickbaity ;)

I’m in a project where writing small Azure functions to accomplish pieces of functionality is a very good fit, and the tasks will be connected in a workflow – Microsoft Flow or Logic Apps. With the latest update for Visual Studio 2017, creating an Azure Function project and publish the function to Azure is super easy.

The tricky part comes when you want to consume those functions somewhere else using a Swagger definition file to describe your API.

The people over at the Azure team has been kind enough to add functionality to automatically generate a Swagger definition. The problem is that the output of this preview functionality is, to put it in nice terms, the equivalent to a table of contents, where the book was left out.

image

There are some blog posts out there on how you can write that book to get a working definition, but manual work when you have already defined the functions pretty well in code is not my cup of tea.

Digression

If an Azure function project had been a WebAPI or similar, you could have installed Swashbuckle, and you would have gotten a nice Swagger definition just like that. The fact that Azure functions are compiled to a class DLL, and that Swashbuckle does not work against a DLL in any easy fashion, I saw two options. A shadow API with Swashbuckle, or roll my own.

I started out with the first option where I created a shadow WebAPI project, copying all my Azure Function signatures, and then manually copying out parts to generate a proper Swagger definition. But I quickly discovered this was still too much manual work for my taste.

Option two it is – generate the mofo myself!

That left me with option two, write my own Swagger generator. The Swagger spec itself is not too complicated, and as Azure uses v2, that’s what I set to use as well. I’m no stranger to reflection on .Net DLL’s, having worked with SharePoint for many years, as well as writing other types of generators, so that’s what I did.

I created an Azure function in my project which at run time reflects on the current assembly, finds all methods marked to be Azure functions, then inspect their ins and outs, and construct a full fledged Swagger definition.

It’s not complicated, but a bit tedious to support all the scenarios I wanted to support. I wanted to support input via the path, as query parameters and JSON objects in the body – which is the most useful one in my opinion. It took me one working day, 7.5h to have this up and ready to go, with ~400 lines of code. Imagine if the Azure team could have spend the same? But then again, I wouldn’t have this blog post :)

Monday, May 15, 2017

Saving a collection of images from PowerApps to SharePoint using Microsoft Flow

Download the sample Flow and PowerApp

Yesterday I wrote about how you can save an image from PowerApps to a SharePoint library using Microsoft Flow – after reading about Paul Culmsee’s approach using Azure Functions. Paul challenged me to save a whole collection of images, and not only one image, so here goes!

This solution loops the images in Flow, but you could easily have looped them in PowerApps as well, saving one image at a time upon submit.

I’ll start with the Flow, and this time we’ll use one input only. And this is where it get’s a bit nasty. A Flow can only accept strings as input from PowerApps, not a collection of items. To overcome this, I’m concatenating the data into one string in the PowerApp, and then splitting the data in the Flow.

The data being passed in looks like this:

Monday, May 15, 2017LT.jpg|data:image/jpeg;base64,<data>#
Monday, May 15, 2017AB.jpg|data:image/jpeg;base64,<data>#


First is the filename with a readable date (borrowed code from Paul), next a pipe | to separate the filename from the base64 encoded image. And at the end a hash # to separate each image from each other.

In Microsoft flow create a new Flow named “Save Images”

Add a “PowerApps” step, followed by a “Compose” step.

image

In the input field for the “Compose” step pick “Ask in PowerApps”. Next change the formula to:

"@split(triggerBody()['Compose_Inputs'], '#')"

and rename the compose action to “Split images” for readability. This will split the incoming string on the character #, creating an array with one item per image.

Note: Remember to include the double quotes around the formula.

image

Below the “Split Images” action, add a “Filter array” action. This action is used to remove the empty element we get at the end when creating the data string in PowerApps. Use the Output from the previous action as the “From” field, click “Edit in advanced mode” and use the following formula to remove empty values. item() will yield one item in an array.

@not(equals(item(), ''))

Note: No quotes here :)

image

Below the Filter array action, add a for each item loop, so that we can process each image sent over.

image

Pick the Body output from the Filter array step as the input in the for each.

image

In the for each action, add two compose steps. Rename one to “Filename” and the other to “File content”.

For filename add the expression:
"@split(item(),'|')[0]"

For file content add the expression:
"@base64ToBinary(replace(split(item(),'|')[1],'data:image/jpeg;base64,',''))"
"@dataUriToBinary(split(item(),'|')[1])"

The effect is that for each item, split on the character |, and assign the left side as the filename, and base64 decode the right side of the split.
Note: Remember to include the double quotes around the formulas.
image

The last part is adding an action step to create a file in SharePoint. Pick a site and library, and assign the values from the previous compose steps.

image

Setting up the PowerApp

image

For the purpose of this demo I have four controls on in my app. A camera control, a button to send it all to flow, a clear button and a gallery to see the images taken, and which will be sent over to SharePoint.

To grab an image I have the following formula on the OnSelect property of the camera control:

Collect(PictureColl,Camera1.Photo)

This stores each image in a collection named PictureColl.

The gallery control’s “Items” property it bound to the PictureColl collection.

The “OnSelect” property of the submit button contains the following formula:

ForAll(PictureColl,Collect(SubmitData, { filename: Concatenate(Text( Now(), DateTimeFormat.LongDate ),Mid("0123456789ABCDEFGHIJKLMNOPQRTSTIUVWXYZ", 1 + RoundDown(Rand() * 36, 0), 1),Mid("0123456789ABCDEFGHIJKLMNOPQRTSTIUVWXYZ", 1 + RoundDown(Rand() * 36, 0), 1),".jpg"), filebody: Url }));

SaveImages.Run(Concat(SubmitData, filename & "|" & filebody & "#"))


The formula creates random filenames with dates and assigns the filename and image date to a collection named SubmitData (borrowed from Paul’s post). Then the file data is concatenated using a pipe | between the filename and the file contents, and concatenated using a hash # between each image. This is then passed into the SaveImages flow I have added to the PowerApp.

If you run the PowerApp (except in the Windows desktop version), tap the camera a couple of times to grab images, and then hit the submit data, you should end up with some images in your library.

image

See my previous post about on how to add a Flow to the PowerApp using PowerApps studio.

Sunday, May 14, 2017

An even more clever workaround for saving photos to SharePoint from PowerApps – using Microsoft Flow

At the time of writing there is a gap using PowerApps with SharePoint which won’t let you save a captured image from PowerApps directly to SharePoint. There are numerous posts out there about this, and Paul Culmsee wrote a post with a clever work around using Azure functions to get the image over to SharePoint.

Paul posted about this in Facebook, and cheeky me replied:
 
image

Note the (not really) at the end there, so I blame Paul entirely for making me write this post, which I think introduce an even more clever way of doing this – doable for any power user out there :D

I’ll skip all the fancy parts which Paul has to get nice random file names etc, so head over to his post for that piece of the pie.

A small note to Paul, and every one else – this will not work for the Windows desktop version of PowerApps – as it stores the captured image different compared to other devices. Instead of using the data uri notation with the full image base64 encoded, it only has a blob reference.

I’ve tested it with great success on:
  • Web
  • Windows Phone – Win10
  • iPad – iOS 10.3.1
So how do you do this? (I strongly urge you to read his post first, as it explains it all in very detail, where as I jump to the gist of things.)

First off, create a new PowerApp and add a camera control to the canvas. For the OnSelect command for the camera add the following command:

ClearCollect(PictureColl,Camera1.Photo)

When you click the image box it will grab the photo, and store it in a collection named PicureColl. As I’m using ClearCollect, the collection will always be cleared first, having one image only in the collection.

image

Next, I added a button which will send the image to SharePoint via Microsoft Flow. So let’s head over to Flow and see what the Flow looks like?

First add a collect from PowerApps actions. Then add a Create file in SharePoint action. For the file name and content, click “Ask in PowerApps”. This will generate two input variables, which we will use to pass in information from the PowerApp to the Flow.

image

Next, add a Compose step between the PowerApps action and the create file in SharePoint action. This is where we will strip away the base64 header, and convert the data to binary. You can type formulas directly into the SharePoint step as well, but I find it easier to manage this way.

The formula in the compose step is:

"@base64ToBinary(replace(triggerBody()['Createfile_FileContent'],'data:image/jpeg;base64,',''))"

"@dataUriToBinary(triggerBody()['Createfile_FileContent'])"

NOTE: It’s important to add the quotes "" before and after the expression, even though they don’t show on edit.

Next change the File Content box to retrieve the Output from the compose step instead of the collect from PowerApps as seen below.

image

And that’s it for the Flow, and head back to the PowerApp. Using PowerApps studio add a Flow to your app.

image

For the OnSelect command for the button add the following:

Saveimage.Run("test.jpg",First(PictureColl).Url)

Saveimage is the name of the Flow, which takes two parameters. The first being the filename, the second being the base64 encoded image from the Url parameter of the image. (All this is in Paul's great post.)

Fire up the app, click once on the image, and once on the button, and you should see a nice picture stored in your SharePoint library.

image

You can very well combine the OnSelect statements into either the image or button control if you want, but that’s all in how you want to have your UI. Having two controls made the demo simpler :)

Thursday, November 3, 2016

Whac-an-MVP - creating a PowerApp Game

PowerApps shows a lot of potential to enable power users to create line of business application for their organizations and teams. It’s cross platform, and I see a lot of good mobile use cases for form entry in the field, where data is then sent back to a central repository. The integration with Flow makes it quite powerful in terms of achieving business processes as well. I’ve dabbled a bit with iAuditor before, and I think PowerApps could solve many of the same cases.

Learning PowerApps

image

When teaching myself new technology I either need a concrete business case or something fun as the basis. Some people got a taste of that at Ignite ;-)

For PowerApps I started out with a proof-of-concept data entry app for a customer, but I cannot disclose details of it yet. In general it shows product information and allows you to visually configure product options and then send an order to a back-end system. In this instance a SharePoint list, but it could very well be some other ERP system.

Wednesday, November 2, 2016

Creating a resize animation in PowerApps

PowerApps made general availability November 1st 2016, and provides a great way for line of business specialists to create no-code applications to solve business challenges they see in their department or team. Once you tapped into data sources and created your logic, you might want to spruce up the application with some animations to make it look a little bit slicker. And that’s the basis of this post.

Read more about PowerApps at https://powerapps.microsoft.com

I’ve recently been developing a couple of PowerApps, and in one of them I wanted to resize an image in a fluid manner before displaying an entry form. There are no built-in transition effects on objects, but by using the timer control you can actually achieve quite a lot.

Your other option is to create the animation somewhere else as either a movie file or gif animation, but where’s the fun in that.

Add an image control and timer control

Image controls can show images from either embedded resources, or from a web address. I’ll go with the latter. Add an image control to your screen and set the Image property to some URL.

image

Resize the image to the start position and add a timer control to the screen and set the Duration property of the control to 2 seconds (2000 milliseconds).

As I want the image to be half the original size, I’m using this formula:

768 - ((384*(Timer1.Value/Timer1.Duration)))

768 is the full height, and 384 is the half of that, so I replace 768 with the formula above, which will over the span of the timer reduce the height of the image down to 384.

image

Start a preview of the screen, click the timer control and watch the animation unfold.

resize-anim

You can of course hide the timer and start that by some other action, but it shows the concept and should get you started. If you want a slower or faster animation, just change the timer duration.