in Flow

Flow: how to upload pictures on demand to SharePoint

I discovered I needed a quick way to upload pictures to SharePoint and I used Microsoft Flow to do it.

I first added a trigger and configured it to accept 4 files as input. I've made the flow in such way that, if I want to change the input to more or less than 4 files, I don't have to change anything in the subsequent steps.

You would think that if we configure the trigger to accept 4 files as input then the trigger will output a JSON array containing 4 objects. Wrong. The trigger body will output a JSON object that will contain the 4 files I uploaded as separate objects. So the triggerbody(), aka the body of the trigger, will return 4 objects inside an object, as you can see below:

 {
"file": {
"contentBytes": "iVBOR…lFTkSuQmCC",
"name": "a great image.png"
},
"file_1": {
"contentBytes": "iVBOR…lFTkSuQmCC",
"name": "another image.png"
},
"file_2": {
"contentBytes": "iVBOR…lFTkSuQmCC",
"name": "yet another image.png"
},
"file_3": {
"contentBytes": "iVBOR…lFTkSuQmCC",
"name": "4th image.png"
}
}

There are a few ways to iterate through these files and upload them to SharePoint. I used the following method:

Initialized an integer variable varNumberOfFiles that will store the total number of files in the body object. The initial value of this variable will be 0.

Initialized a boolean variable varIsLastFile. I will use this variable to check if the file we're processing is the last one. The initial value of this variable will be an expression that will return false. Note that you can't initialize a boolean variable with a "false" or "true" string, it has to be a false or true boolean value which you can return from an expression.

Initialized an object variable varFileObject that will store the file object for upload. I left the initial value empty because I configured the flow to run even if I don't upload any files.

Added a Do until container which I will use to loop through files until I reach the last file. So the condition for this do until will be varIsLastfile is equal to true or, if you like the advanced mode, the condition will look like this: @equals(variables('varIsLastFile'), true)

Inside the Do until container, I added an action to set the varIsLastFile variable to the result returned by this expression:

not(contains(triggerBody(),if(equals(variables('varNumberOfFiles'), 0), 'file', concat('file_', string(variables('varNumberOfFiles'))))))

This expression takes the triggerBody() output and, if this is the first do until iteration, then varNumberOfFiles is 0 (because we haven't incremented it yet) and it will look for an object that's named file. Else, it's going to look for files named file_1file_2file_3file_4, etc

If you look at the body output I posted at the beginning of this article, the name file is the default object name for the first file in the body object.

 "file": {
"contentBytes": "iVBOR…lFTkSuQmCC",
"name": "a great image.png"
}

The rest of the files have an underscore and a number added to their object names.

 
"file_1": {
"contentBytes": "iVBOR…lFTkSuQmCC",
"name": "another image.png"
},
"file_2": {
"contentBytes": "iVBOR…lFTkSuQmCC",
"name": "yet another image.png"
},
"file_3": {
"contentBytes": "iVBOR…lFTkSuQmCC",
"name": "4th image.png"
}

In the expression above, in the false condition of the contains function I am using concat('file_', string(variables('varNumberOfFiles'))) to get the file names by concatenating the text file_ and the number returned by the variable varNumberOfFiles

So if varNumberOfFiles is 0, then return file, else return file_1file_n. If the body contains an object with the name file or file_1file_n then check if such file exists in the triggerBody() and use not to return true if there is no such file or false if such file exists.

Then I added a condition to check if varIsLastFile is equal to false. If it's false, then we haven't processed the last file yet, so the flow will proceed to create the file in SharePoint. I realize I should have named the variable "varNoMoreFiles" instead of varIsLastFile but it's too late now. 🙂

In the Yes container of the condition I added two actions. One to set the varFileObject to the current file object and another one to create the file in SharePoint.

I've set the value of varFileObject to this expression: triggerBody()?[concat('file', if(equals(variables('varNumberOfFiles'), 0), ", concat('_', string(variables('varNumberOfFiles')))))]

This expression uses the same logic as the previous expression I used in the Set variable varIsLastFile action to get the file identifier and will return the JSON object containing the file name and contentBytes

The Create file action is configured to create the files in the Uploads from Mobile folder and uses the result returned by the variables('varFileObject')?['name'] expression as file name and the result from base64ToBinary(variables('varFileObject')?['contentBytes']) as file content. variables('varFileObject')?['contentBytes'] represents the content encoded in base64 and I used base64ToBinary() function to decode it and get the binary content.

The last action is to increment the varNumberOfFiles variable before the Do until loops again.:

Putting everything together:

This is how it works when using the Flow app for Android. I tapped on the Buttons menu to see all my buttons and then tapped on the Upload file from mobile on demand button:

I'm presented with the file selection options:

I'm browsing for images on my phone. Note that selecting files (documents) is not supported on mobile:

I selected 4 files and tapped DONE:

I can see that the flow started:

Then I can see the files on SharePoint:

If you like this flow you can download it from here.

Write a Comment

Comment

  • Related Content by Tag