Is there any way to compose the request URL somehow without if-else structure?
I'm trying to build a URL for the request to another service. There are 5 parameters, 1 parameter is obligatory, while the other 4, are optional.
Example: https://web-site.com/v1/assets?author=${id}&category=cat&page=1&per-page=1&sort=abc
author
-- is the obligatory parameter.
Other parameters can be passed independently.
Examples:
https://web-site.com/v1/assets?author=${id}&category=cat&page=1&per-page=1&sort=abc
https://web-site.com/v1/assets?author=${id}&per-page=1&sort=abc
https://web-site.com/v1/assets?author=${id}&sort=abc
https://web-site.com/v1/assets?author=${id}&category=cat&sort=abc
https://web-site.com/v1/assets?author=${id}&category=cat
I'm trying it build the URL in this way:
import { QueryDto } from '../types/dtos/query.dto'
export function urlComposer(id: string, query: QueryDto) {
if (
query.author != undefined &&
query.category != undefined &&
query.page != undefined &&
query.perPage != undefined &&
query.sort != undefined) {
return`https://web-site.com/v1/assets?author=${id}&category=${query.category}&page=${query.page}&per-page=${query.perPage}&sort=${query.sort}`
} else if (
query.author != undefined &&
query.category != undefined &&
query.page != undefined &&
query.perPage != undefined
) {
return`https://web-site.com/v1/assets?author=${id}&category=${query.category}&page=${query.page}&per-page=${query.perPage}`
} else if (
query.author != undefined &&
query.category != undefined &&
query.page != undefined
) {
return`https://web-site.com/v1/assets?author=${id}&category=${query.category}&page=${query.page}`
} else if (
query.author != undefined &&
query.category != undefined
) {
return`https://web-site.com/v1/assets?author=${id}&category=${query.category}`
} else if (
query.author != undefined &&
query.sort != undefined
) {
return`https://web-site.com/v1/assets?author=${id}&sort=${query.sort}`
} else {
return`https://web-site.com/v1/assets?author=${id}`
}
}
QueryDto.ts
import { ApiProperty } from '@nestjs/swagger'
export class QueryDto {
@ApiProperty()
author: string
@ApiProperty({required: false})
category?: string
@ApiProperty({required: false})
page?: number
@ApiProperty({required: false})
perPage?: number
@ApiProperty({required: false})
sort?: string
}
I believe that exists a simpler way to complete such URL in runtime, do you have any references or your own solution?
CodePudding user response:
Sure, you need to get the key/value pairs from the input object using Object.entries()
, filter the resulting array depending on whether there is a value, then convert it into the querystring. Like this:
class QueryDto {
author?: string
category?: string
page?: number
perPage?: number
sort?: string
}
function urlComposer(id: string, query: QueryDto) {
const queryString = Object.entries({ id, ...query })
.filter(([,value]) => value)
.map(([key, value]) => `${key}=${value}`)
.join('&')
return `https://web-site.com/v1/assets?${queryString}`
}
const result = urlComposer('foo', {
author: 'me',
category: 'books'
})
console.log(result) // https://web-site.com/v1/assets?id=foo&author=me&category=books"