Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[typescript-axios] doesn't serialize deepObject query params #7564

Open
5 tasks done
wamujlb opened this issue Oct 1, 2020 · 10 comments
Open
5 tasks done

[typescript-axios] doesn't serialize deepObject query params #7564

wamujlb opened this issue Oct 1, 2020 · 10 comments

Comments

@wamujlb
Copy link

wamujlb commented Oct 1, 2020

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
    input: {day: 20, year: {min: 1990, max: 2000}}
    actual output: ?day=20&year
    expected output: ?day=20&year[min]=1990&year[max]=2000
Description

I'm using [typescript-axios] api client generator. Some of the properties I pass to it specified as deepObject. It looks that it doesn't support this type of args at all. Is there any possible ways to fix it?

openapi-generator version

v4.3.1
v5.0.0-beta

OpenAPI declaration file content or url
YearRange:
      in: query
      name: year
      required: false
      style: deepObject
      schema:
        type: object
        properties:
          min:
            type: string
            example: 2010
          max:
            type: string
            example: 2019
Generation Details

[typescript-axios] generator

Steps to reproduce
Related issues/PRs

#6075

Suggest a fix

Replace old deprecated url API with URLSearchParams.

@auto-labeler
Copy link

auto-labeler bot commented Oct 1, 2020

👍 Thanks for opening this issue!
🏷 I have applied any labels matching special text in your issue.

The team will review the labels and make any necessary changes.

@tsraza
Copy link

tsraza commented Oct 2, 2020

@wamujlb do you have a snippet to work around this?

@tsraza
Copy link

tsraza commented Dec 9, 2020

i did this on the generated file

sed -i "s/localVarQueryParameter\['filter'\] \= filter/localVarQueryParameter\['filter'\] \= JSON.stringify(filter)/g" api.ts

@wamujlb
Copy link
Author

wamujlb commented Feb 16, 2021

@tsraza this will not work in my case. API expects something like this:

{date: 'desc'} => ?sort[date]=desc.

@wamujlb
Copy link
Author

wamujlb commented Feb 16, 2021

I have made a workaround but I think that it will be good to add it to the generator.

export const setSearchParams = function (url: URL, ...objects: any[]) {
    const searchParams = new URLSearchParams(url.search);
    for (const object of objects) {
        for (const key in object) {
            /**
             * @workaround
             * Convert object value to the string
             * {sort: {date: 'desc', order: 'asc'}} => 'sort[date]=desc&sort[order]=asc'
             */
            const value = object[key];

            if(typeof value === 'object'){
                Object.entries(value).forEach(([entryKey, entryValue]) => {
                    searchParams.set(`${key}[${entryKey}]`, String(entryValue));
                })
            } else {
                searchParams.set(key, value);
            }
        }
    }
    url.search = searchParams.toString();
}

@ruiaraujo012
Copy link

Any update on this?

@kamilkn
Copy link

kamilkn commented Mar 12, 2022

Any update on this?

++, nothing changed

@talss89
Copy link

talss89 commented May 29, 2022

I've just had a similar problem. Loopback 4 expects filter parameters as serialised JSON.

It can be solved in a 'nice' way using template overrides.

I modified the template to serialise any object passed as a parameter to JSON:

if(typeof {{paramName}} === 'object' && {{paramName}} !== null)
    localVarQueryParameter['{{baseName}}'] = JSON.stringify({{paramName}});
else
    localVarQueryParameter['{{baseName}}'] = {{paramName}};

@wamujlb - In your case, you could probably add your code to the template.

@RapGeneral
Copy link

RapGeneral commented Jul 11, 2022

In my case I updated the common.mustache template with @wamujlb's answer. Its working as expected.
But it really would be great to add this to the default templates.

@tokidoki11
Copy link

FYI since array is not being handled well, i updated based on @wamujlb answer

export const setSearchParams = function (url: URL, ...objects: any[]) {
    const searchParams = new URLSearchParams(url.search);
    for (const object of objects) {
        for (const key in object) {
            /**
             * @workaround for deep object
             * Convert object value to the string
             * {sort: {date: 'desc', order: 'asc', multiple: ['1','2']}} => 'sort[date]=desc&sort[order]=asc&multiple[]=1&multiple[]=2'
             */
            const value = object[key];

            if(typeof value === 'object'){
                Object.entries(value).forEach(([entryKey, entryValue]) => {
                    if(Array.isArray(entryValue)){
                        entryValue.forEach((item) => {
                            searchParams.append(`${key}[${entryKey}][]`, String(item));
                        })
                    }
                    else {
                        searchParams.set(`${key}[${entryKey}]`, String(entryValue));
                    } 
                })
            } else {
                searchParams.set(key, value);
            }
        }
    }
    url.search = searchParams.toString();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants