From 9e9cb903456c0799fc657c3c1df2de8704c5f39b Mon Sep 17 00:00:00 2001 From: "Ronald A. Richardson" Date: Thu, 16 May 2024 20:49:42 +0800 Subject: [PATCH] improve fetch service and fix handling of download method --- addon/services/fetch.js | 27 +++++++++++++++--------- addon/utils/is-empty-object.js | 3 +++ app/utils/is-empty-object.js | 1 + tests/unit/utils/is-empty-object-test.js | 10 +++++++++ 4 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 addon/utils/is-empty-object.js create mode 100644 app/utils/is-empty-object.js create mode 100644 tests/unit/utils/is-empty-object-test.js diff --git a/addon/services/fetch.js b/addon/services/fetch.js index 2f094e1..79fbcb6 100644 --- a/addon/services/fetch.js +++ b/addon/services/fetch.js @@ -15,6 +15,7 @@ import corslite from '../utils/corslite'; import getMimeType from '../utils/get-mime-type'; import download from '../utils/download'; import getUserOptions from '../utils/get-user-options'; +import isEmptyObject from '../utils/is-empty-object'; import fetch from 'fetch'; if (isBlank(config.API.host)) { @@ -339,7 +340,7 @@ export default class FetchService extends Service { return this.cachedGet(...arguments); } - const urlParams = !isBlank(query) ? new URLSearchParams(query).toString() : ''; + const urlParams = !isEmptyObject(query) ? new URLSearchParams(query).toString() : ''; return this.request(`${path}${urlParams ? '?' + urlParams : ''}`, 'GET', {}, options); } @@ -506,7 +507,7 @@ export default class FetchService extends Service { let version = options?.version ?? 'v1'; let host = options?.host ?? `https://${options?.subdomain ?? 'routing'}.fleetbase.io`; let route = coordinates.map((coords) => coords.join(',')).join(';'); - let params = !isBlank(query) ? new URLSearchParams(query).toString() : ''; + let params = !isEmptyObject(query) ? new URLSearchParams(query).toString() : ''; let path = `${host}/${service}/${version}/${profile}/${route}`; let url = `${path}${params ? '?' + params : ''}`; @@ -601,16 +602,22 @@ export default class FetchService extends Service { const method = options.method ?? 'GET'; const credentials = options.credentials ?? this.credentials; const baseUrl = `${options.host || this.host}/${options.namespace || this.namespace}`; - const params = method.toUpperCase() === 'GET' ? `?${!isBlank(query) ? new URLSearchParams(query).toString() : ''}` : ''; - const body = method.toUpperCase() !== 'GET' ? JSON.stringify(query) : {}; + const isReadOnlyRequest = ['GET', 'HEAD'].includes(method.toUpperCase()); + const params = isReadOnlyRequest && !isEmptyObject(query) ? `?${new URLSearchParams(query).toString()}` : ''; + const body = !isReadOnlyRequest ? JSON.stringify(query) : {}; + const fetchOptions = { + method, + credentials, + headers, + }; + + // Only supply body to fetch if not GET or HEAD request + if (!isReadOnlyRequest) { + fetchOptions.body = body; + } return new Promise((resolve, reject) => { - return fetch(`${baseUrl}/${path}${params}`, { - method, - credentials, - headers, - body, - }) + return fetch(`${baseUrl}/${path}${params}`, fetchOptions) .then((response) => { options.fileName = this.getFilenameFromResponse(response, options.fileName); options.mimeType = this.getMimeTypeFromResponse(response, options.mimeType); diff --git a/addon/utils/is-empty-object.js b/addon/utils/is-empty-object.js new file mode 100644 index 0000000..28073d2 --- /dev/null +++ b/addon/utils/is-empty-object.js @@ -0,0 +1,3 @@ +export default function isEmptyObject(obj) { + return Object.keys(obj).length === 0 && obj.constructor === Object; +} diff --git a/app/utils/is-empty-object.js b/app/utils/is-empty-object.js new file mode 100644 index 0000000..63726f8 --- /dev/null +++ b/app/utils/is-empty-object.js @@ -0,0 +1 @@ +export { default } from '@fleetbase/ember-core/utils/is-empty-object'; diff --git a/tests/unit/utils/is-empty-object-test.js b/tests/unit/utils/is-empty-object-test.js new file mode 100644 index 0000000..eb8285d --- /dev/null +++ b/tests/unit/utils/is-empty-object-test.js @@ -0,0 +1,10 @@ +import isEmptyObject from 'dummy/utils/is-empty-object'; +import { module, test } from 'qunit'; + +module('Unit | Utility | is-empty-object', function () { + // TODO: Replace this with your real tests. + test('it works', function (assert) { + let result = isEmptyObject(); + assert.ok(result); + }); +});