From ba1538325851659fa2c1cbbd353340169889c54c Mon Sep 17 00:00:00 2001 From: Marcelo Lauxen Date: Wed, 28 Jul 2021 08:05:01 -0300 Subject: [PATCH] Make query: to accept a FormData or a URLSearchParams --- README.md | 2 ++ src/fetch_request.js | 16 +++++++++++----- src/lib/utils.js | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 254bf3c..4c4fc1d 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,8 @@ Adds additional headers to the request. `X-CSRF-Token` and `Content-Type` are a Appends query parameters to the URL. Query params in the URL are preserved and merged with the query options. +Accepts `Object`, `FormData` or `URLSearchParams`. + ##### responseKind Specifies which response format will be accepted. Default is `html`. diff --git a/src/fetch_request.js b/src/fetch_request.js index d3e21db..5e62065 100644 --- a/src/fetch_request.js +++ b/src/fetch_request.js @@ -1,6 +1,6 @@ import { FetchResponse } from './fetch_response' import { RequestInterceptor } from './request_interceptor' -import { getCookie, compact, metaContent } from './lib/utils' +import { getCookie, compact, metaContent, stringEntriesFromFormData, mergeEntries } from './lib/utils' export class FetchRequest { constructor (method, url, options = {}) { @@ -18,6 +18,7 @@ export class FetchRequest { } catch (error) { console.error(error) } + const response = new FetchResponse(await window.fetch(this.url, this.fetchOptions)) if (response.unauthenticated && response.authenticationURL) { @@ -97,12 +98,17 @@ export class FetchRequest { const originalQuery = (this.originalUrl.split('?')[1] || '').split('#')[0] const params = new URLSearchParams(originalQuery) - if (this.options.query) { - for (const [key, value] of Object.entries(this.options.query)) { - params.append(key, value) - } + let requestQuery = this.options.query + if (requestQuery instanceof window.FormData) { + requestQuery = stringEntriesFromFormData(requestQuery) + } else if (requestQuery instanceof window.URLSearchParams) { + requestQuery = requestQuery.entries() + } else { + requestQuery = Object.entries(requestQuery || {}) } + mergeEntries(params, requestQuery) + const query = params.toString() return (query.length > 0 ? `?${query}` : '') } diff --git a/src/lib/utils.js b/src/lib/utils.js index 3eb2e60..ec127c1 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -29,3 +29,22 @@ export function metaContent (name) { const element = document.head.querySelector(`meta[name="${name}"]`) return element && element.content } + +export function stringEntriesFromFormData (formData) { + return [...formData].reduce((entries, [name, value]) => { + return entries.concat(typeof value === 'string' ? [[name, value]] : []) + }, []) +} + +export function mergeEntries (searchParams, entries) { + for (const [name, value] of entries) { + if (value instanceof window.File) continue + + if (searchParams.has(name)) { + searchParams.delete(name) + searchParams.set(name, value) + } else { + searchParams.append(name, value) + } + } +}