Document Libraries are an integral part of SharePoint sites and are super helpful, so today, we will explore how to check if a document library exists. The idea is not to create one, although we’ll do that in the future, to know if we have a document library on a SharePoint site or not.
As always, we’ll define all the concepts, but if you’re in a hurry, you can get the template directly from my cookbook section.
Find a document list in a SharePoint site.
The template will help you check if the SharePoint site has a document library. It requires two parameters; the first is the site you want to match, and the second is the document library.
You may wonder why it is useful? Imagine that you have a lot of sites, and you want to automate the creation of a new document library that is common to all of them. Instead of going to the websites one by one, you can create a Flow that collects a list of sites and checks (and creates) them automatically.
So let’s look at this template works and how you can take advantage of it.
The HTTP way
First, let’s think about how to achieve this. SharePoint has a convenient action called “Send an HTTP request to SharePoint Action.” It enables us to get information from SharePoint’s API, even if there isn’t an action available in Power Automate to do it.
It’s essential before we go further to say that Microsoft defines the structure of the requests and overall organization, meaning that some things may look strange to you, but there’s not a lot that we can do about it. The API has a lot of endpoints that you can explore, but today we’ll use only one to get the document libraries and their information.
The template
So let’s start building the template. The main objective is, aside from finding a document library, to be able to use it in your tenant, hence the “Manually trigger a Flow” trigger and the “Respond to a PowerApp or flow”.
Here’s the overview of the template.
First, we get the site and document library we want to find. Then, define a variable that will contain the information if it exists or not, send a request to see it, parse the data and return the results.
Let’s explore each step individually.
The trigger
We could use a fixed URL to get the information, but that wouldn’t make it global. We would need to change any other site, and that’s not good, so we use the first parameter to get the URL of the SharePoint site that we want to check.
The SharePoint site URL should be something like this:
https://<tenant>.sharepoint.com/sites/<site_name>
Please don’t put anything after it. You can, but you may have some issues in the process.
The trigger is quite simple, so let’s move forward.
The variable
The variable is used to store if the document library exists or not.
The default value is false, and this is used in the last step to return the information.
We’ll go over more detail on how it works in the following steps, but we define it as the “default” value “not finding” the document library unless we find it.
The SharePoint call
I consider this part the “tricky,” but let’s check it slowly. Here’s what it looks like.
The first parameter is the site from the “Manually trigger a Flow” trigger that defines the site we want to check.
If you don’t know how to work with APIs, don’t work. The “GET” is a method that is a flag to the backend system that we want to get data. There are others like “POST” or “DELETE,” for example. Developers use these to segment the types of actions that we want to perform. For example, if you have the same URL and do a “GET,” then you want to “get” information from it, but if you make a “DELETE” request, then you expect that the backend will delete your record. It all depends on how it’s implemented but having a standard convention helps a lot.
Now let’s look at the URI. When we call an API, we have the base URL (the site’s URL), and the remaining tells the backend what we want to do.
_api/web/lists?$filter=BaseTemplate eq 101
We’re accessing the lists part of the API, and we want to filter by something. It’s also common to call this as an endpoint, so the endpoint for the lists would be _api/web/lists
.
Now let’s look at a request without the filter first and see what we get. Here’s what our site looks like.
We get a lot of information from SharePoint per item in the list. So the intuitive way to do things would be to use the “Parse JSON” action and return the previous call as a template. That makes sense, but you will get issues when running your Flow. Why? Because of two behaviors of both Power Automate and SharePoint:
- Flow defines the fields in the sample mandatory when building the template.
- When SharePoint returns the results, it will only return results for the data fields that contain data.
Together, these two things will crash almost 100% of the time. I know it sucks, but in this case, you should not use the “Parse JSON” action and instead write the expressions yourself. It’s much easier to find the values in the “Dynamic Content” tab, but it’s not possible in this case. I say almost 100% of the time because it would be scarce that all lists you have are the same time and only that type.
Finally, let’s understand why we’re filtering the data. When defining something as a “document library,” SharePoint does two things in the background. The first is creating a list, and the second is applying a template that “configures” things as a document library and something familiar to you. So a document library is a list with template ID 101. Why 101? Microsoft defined it this way. There are many types, as you can see here, like contacts, meetings, and tasks, to name a few, but the underlying technology are always lists.
We could call the API and get all data and then filter it, but it would be wasteful since there may be a lot of lists, so it’s much better to filter the data before it’s returned.
Finding our document library
So now that we have the document libraries from SharePoint, we can filter the data and check if we can find the one we’re looking for. If you skipped the previous section, you must know that we’ll define the fields manually instead of picking them from the “dynamic content” tab. Here’s an overview of the “apply to each” action.
First, we’ll need to go over all elements of the array. If you’re not familiar with JSON, don’t worry. I’ll create a more in-depth explanation of it, but here’s what you need to understand. When you have curly braces, you have an “object,” in this case, a SharePoint list or document library to be more precise. Consider an object as group of key and values. For example, a “car”, object can have the key “brand” with value “BMW” and the “color” key with the value “blue”. When you have square braces, you know you’ll have a list of objects, so in this case, a group of SharePoint lists. All of them are identified by a key. Consider the key as a way to tell Power Automate where to find the data.
We want to provide the “apply to each” action with the array of items so that it can iterate between them, but to do that we need to understand what SharePoint returns. Let’s look at what SharePoint returned to us:
I’ve collapsed the result so that we can see it better. As you can see, we have an object called “d” that contains another object called “results,” and the “results” object is a group of other objects. So we can’t only provide the “d” to the “apply to each” action because that doesn’t contain an array. So here’s what we need to provide:
body('Send_an_HTTP_request_to_SharePoint')?['d']?['results']
If you’re copying directly to your Flow, please don’t forget to encircle the above result with { } , like:
@{body('Send_an_HTTP_request_to_SharePoint')?['d']?['results']}
So we want the body of the request (and for that, we use the body function), and after that, we have the question mark. It means that we want to fetch the body, and then if the key is available (in this case, “d”), we want the value. If we didn’t include the question mark, we would be telling Power Automate that it’s mandatory, so it will fail if it doesn’t exist. After that, we do the same for the “results” key. We either get nothing, and the Power Automate skips the “apply to each” action, or we have an array, and we can process it.
Finally, let’s process the array. Again the same strategy as before. We’ll write it ourselves since we don’t have an available choice in the “dynamic fields.”
items('Apply_to_each')?['EntityTypeName']
To do that, we use the items function to get the value that we need, the “EntityTypeName.” We employ the same strategy as before. We use the question mark to indicate that we would like to get a value, but it’s not mandatory to get one.
We use a compose action instead of a variable because it’s easier to use. A variable would require two actions (initialize and set it), so it’s faster to do it this way, but you’re free to use a variable if you want.
Finally, let’s make the comparison. We’ll use the previous compose and the parameter from the “Manually trigger a Flow” trigger.
If they are the same, it’s already present on the SharePoint lists’ objects. Therefore, we update the variable to “true” using the “true” function.
I like to include a return action called “Respond to a PowerApp or flow” that will return the variable’s value (whether we found it or not). If you want to re-use the Flow multiple times, you need this action, otherwise the parent Flow would not know that the child Flow ended.
Final thoughts
I know that I go into many details, and this article is no exception, but it’s important for me that you understand each step and especially some of the “gotchas” that you can find. It’s simple, but if you try to do it the “usual” way by using the “Parse JSON” action, you will have a failing Flow. I think this solution is a lot better and it’s not a lot of work once you undestsnat what’s being done.
Photo by Niklas Ohlrogge on Unsplash
Hi Manuel
I have recreated your flow, but it gets lost when looking at the array of document libraries . The flow has run for 10 minutes with no output from that “Apply To Each”.
Any Ideas ?
Thanks
Nigel