{"id":1146,"date":"2021-01-20T11:03:19","date_gmt":"2021-01-20T17:03:19","guid":{"rendered":"http:\/\/ninmonkeys.com\/blog\/?p=1146"},"modified":"2021-01-20T12:27:58","modified_gmt":"2021-01-20T18:27:58","slug":"web-contents-using-dynamic-and-duplicate-key-names-in-a-query","status":"publish","type":"post","link":"https:\/\/ninmonkeys.com\/blog\/2021\/01\/20\/web-contents-using-dynamic-and-duplicate-key-names-in-a-query\/","title":{"rendered":"Web.Contents: Using Dynamic and Duplicate key names in a Query"},"content":{"rendered":"\n\n\n<p><a href=\"https:\/\/discord.gg\/9StERjyPEY\">Power BI Discord<\/a> asked the question:<br>&gt; How do you use <strong>duplicate keys<\/strong>, and <strong>dynamic urls<\/strong> with <code class=\"\" data-line=\"\">&lt;a href=&quot;https:\/\/docs.microsoft.com\/en-us\/powerquery-m\/web-contents&quot;&gt;Web.Contents&lt;\/a&gt;<\/code> ? <br>(They were using a web API that required duplicate keys) <br>After I wrote this, <a href=\"#Easier_Solution\" data-type=\"internal\" data-id=\"#Easier_Solution\">Chris Webb found an easier solution<\/a>.<\/p>\n\n\n\n<h2>Requirements<\/h2>\n\n\n\n<ol><li>You can&#8217;t use a regular <code class=\"\" data-line=\"\">record<\/code> because keys must be distinct. <code class=\"\" data-line=\"\">Query = [ Key1 = 1, Key1 = 10]<\/code> will throw an error.<\/li><li>You can&#8217;t put the **dynamic url** in the first argument <code class=\"\" data-line=\"\">Web.Contents<\/code> or else refreshes can break<\/li><\/ol>\n\n\n\n<p>I built a <code class=\"\" data-line=\"\">RelativePath<\/code> by Uri-escaping a list. <\/p>\n\n\n\n<h2>Building <code class=\"\" data-line=\"\">RelativePath<\/code> by Uri-escaping a list<\/h2>\n\n\n\n<p>The final query will request the url: <a href=\"https:\/\/www.google.com\/search?q=dog&amp;q=cat\">https:\/\/www.google.com\/search?q=dog&amp;q=cat<\/a><br>This function generates the query string  <code class=\"\" data-line=\"\">q=dog&amp;q=cat<\/code> <\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td>This Input<\/td><td><code class=\"\" data-line=\"\">&quot;q&quot;, { &quot;dog&quot;, &quot;cat&quot; }<\/code><\/td><\/tr><tr><td>Will Return<\/td><td><code class=\"\" data-line=\"\">q=dog&amp;q=cat<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">let\n    QueryStr_UsingDuplicateKeys = (key as text, values as list) as text =&gt;\n    \/\/ values are the &#039;value&#039; of &#039;key&#039;-&gt; &#039;value&#039; pairs\n        let\n            escapedList = List.Transform(\n                values,\n                each \n                    key &amp; &quot;=&quot; &amp; Uri.EscapeDataString( Text.From(_) )\n            ),    \n            joinedArgs = Text.Combine(escapedList, &quot;&amp;&quot;)\n        in\n            joinedArgs\nin\n    QueryStr_UsingDuplicateKeys<\/code><\/pre>\n\n\n\n<p>Now you can use <code class=\"\" data-line=\"\">Web.Contents<\/code> as normal. <\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">let\n    BaseUrl = &quot;https:\/\/www.google.com&quot;,\n    queryStr = QueryStr_UsingDuplicateKeys(\n        &quot;q&quot;, {&quot;dog&quot;, &quot;cat&quot;}\n    ),\n    Options = [\n        RelativePath = &quot;\/search?&quot; &amp; queryStr,\n        Headers = [ Accept=&quot;application\/json&quot; ]\n    ],\n    response_binary = Web.Contents(BaseUrl, Options)\nin\n    response_binary<\/code><\/pre>\n\n\n\n<p>Note: <code class=\"\" data-line=\"\">BaseUrl<\/code> is for the static part of the url. Everything else should be in <code class=\"\" data-line=\"\">options[RelativePath]<\/code> or <code class=\"\" data-line=\"\">options[Query]<\/code> See <a href=\"https:\/\/docs.microsoft.com\/en-us\/powerquery-m\/web-contents\">docs: Web.Contents <\/a>for details.<\/p>\n\n\n\n<h2>Easier Solution<\/h2>\n\n\n\n<p>First try <a href=\"https:\/\/blog.crossjoin.co.uk\/2021\/01\/10\/handling-multiple-url-query-parameters-with-the-same-name-using-web-contents-in-power-query-power-bi\/\">Chris&#8217;s method where you use <code class=\"\" data-line=\"\">Query<\/code>&#8216;s Key-Value pairs a list<\/a><br><a href=\"https:\/\/curatedsql.com\/2021\/01\/11\/handling-duplicate-query-string-values-with-power-query\/\">Results may vary<\/a>. If it does not work, you can try this method.<br>I have not seen <code class=\"\" data-line=\"\">Query<\/code> publicly documented.<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container\">\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">Query = [\n    q = {&quot;dog&quot;, &quot;cat&quot;}\n]<\/code><\/pre>\n<\/div><\/div>\n\n\n\n<h2>Tips from Chris Webb<\/h2>\n\n\n\n<h3>Using Optional Parameters with Query<\/h3>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-chris-webb-039-s-bi-blog wp-block-embed-chris-webb-039-s-bi-blog\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"dAelEea0Ox\"><a href=\"https:\/\/blog.crossjoin.co.uk\/2021\/01\/10\/handling-multiple-url-query-parameters-with-the-same-name-using-web-contents-in-power-query-power-bi\/\">Handling Multiple URL Query Parameters With The Same Name Using Web.Contents In Power Query\/Power BI<\/a><\/blockquote><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Handling Multiple URL Query Parameters With The Same Name Using Web.Contents In Power Query\/Power BI&#8221; &#8212; Chris Webb&#039;s BI Blog\" src=\"https:\/\/blog.crossjoin.co.uk\/2021\/01\/10\/handling-multiple-url-query-parameters-with-the-same-name-using-web-contents-in-power-query-power-bi\/embed\/#?secret=dAelEea0Ox\" data-secret=\"dAelEea0Ox\" width=\"580\" height=\"327\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><figcaption><a href=\"http:\/\/This example requests the url http:\/\/jsonplaceholder.typicode.com\/comments\">Chris<\/a> has a tip to optionally use null query parameters.<br>If set to an empty list, <code class=\"\" data-line=\"\">{}<\/code> &#8212; the request drops the parameter.<\/figcaption><\/figure>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">Web.Contents(\n    &quot;http:\/\/jsonplaceholder.typicode.com\/comments&quot;,\n    [Query = [postId = {}] ]\n)<\/code><\/pre>\n\n\n\n<p>Which results in the url: <code class=\"\" data-line=\"\">&lt;a href=&quot;http:\/\/jsonplaceholder.typicode.com\/comments&quot;&gt;http:\/\/jsonplaceholder.typicode.com\/comments&lt;\/a&gt;<\/code><br>This is a good place to use <strong>Power Query<\/strong>&#8216;s <code class=\"\" data-line=\"\">null coalesce<\/code> operator  (<a href=\"https:\/\/docs.microsoft.com\/en-us\/powerquery-m\/m-spec-operators\">Which isn&#8217;t in the official docs<\/a>) <\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-typescript\" data-line=\"\">Query = [postId = myPostId ?? {}]<\/code><\/pre>\n\n\n\n<h3>Capturing HTTP Requests without Fiddler<\/h3>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-chris-webb-039-s-bi-blog wp-block-embed-chris-webb-039-s-bi-blog\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"yhu0rMyine\"><a href=\"https:\/\/blog.crossjoin.co.uk\/2019\/11\/17\/troubleshooting-web-service-refresh-problems-in-power-bi-with-the-power-query-diagnostics-feature\/\">Troubleshooting Web Service Refresh Problems In Power BI With The Power Query Diagnostics Feature<\/a><\/blockquote><iframe class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; clip: rect(1px, 1px, 1px, 1px);\" title=\"&#8220;Troubleshooting Web Service Refresh Problems In Power BI With The Power Query Diagnostics Feature&#8221; &#8212; Chris Webb&#039;s BI Blog\" src=\"https:\/\/blog.crossjoin.co.uk\/2019\/11\/17\/troubleshooting-web-service-refresh-problems-in-power-bi-with-the-power-query-diagnostics-feature\/embed\/#?secret=yhu0rMyine\" data-secret=\"yhu0rMyine\" width=\"580\" height=\"327\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><figcaption>The <strong>Query Editor<\/strong> is an alternate to using <strong>Fiddler <\/strong>to capture web requests.<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Power BI Discord asked the question:&gt; How do you use duplicate keys, and dynamic urls with &lt;a href=&quot;https:\/\/docs.microsoft.com\/en-us\/powerquery-m\/web-contents&quot;&gt;Web.Contents&lt;\/a&gt; ? (They were using a web API that required duplicate keys) After I wrote this, Chris Webb found an easier solution. Requirements You can&#8217;t use a regular record because keys must be distinct. Query = [ Key1 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13,9],"tags":[62,7,64],"_links":{"self":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1146"}],"collection":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/comments?post=1146"}],"version-history":[{"count":84,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1146\/revisions"}],"predecessor-version":[{"id":1420,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/posts\/1146\/revisions\/1420"}],"wp:attachment":[{"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/media?parent=1146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/categories?post=1146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ninmonkeys.com\/blog\/wp-json\/wp\/v2\/tags?post=1146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}