DEV Community

Cover image for Why you should use URL Constructor instead of template literals
Leonardo Theodoro
Leonardo Theodoro

Posted on • Edited on

Why you should use URL Constructor instead of template literals

Hey everyone! Today, I'm sharing a quick tip that improved the semantics of my code significantly.

Often, whether working in frontend or backend development, we need to construct URLs with parameters, right?

I used to write the URLs of my requests like this:

const url = `http://localhost:3000/endpoint?param1=${var1}&param2=${var2}&param3=${var3}`
Enter fullscreen mode Exit fullscreen mode

We agree that this URL is hard to read and maintain; we always need to identify which parts are parameters, which are variables, and which are just Javascript syntax.

To address this semantic issue, I discovered the URL Constructor, which accomplishes the same task but in more efficient and elegant way.

Now, we can rewrite the same code like this:

const url = new URL('http://localhost:3000/endpoint')

url.searchParams.set('param1', var1)
url.searchParams.set('param2', var2)
url.searchParams.set('param3', var3)
Enter fullscreen mode Exit fullscreen mode

The code clearly indicates what it's doing. In the first line, we create the base URL and in the subsequent lines, we add the necessary search parameters.

Done. Now, the variable url contains the same search parameters as before, but now we are using the URL class, making the code much simpler and easier to maintain.

What about you? Have you used the URL class before? Maybe for another purpose? Feel free to share your experiences with me.

Top comments (5)

Collapse
 
lionelrowe profile image
lionel-rowe • Edited

this URL is hard to read and maintain

That's not the main problem with it. The main problem is that there's no escaping of the interpolated variables. If you use URL#searchParams instead, you get context-sensitive escaping for free.

const val = '1&y=2'

// naive interpolation
{
    const href = `https://example.com/?x=${val}`

    printTestResults(href)
    // `href`: https://example.com/?x=1&y=2
    // ❌ `x` value changed: true
    // ❌ `y` value set: true
}

// URL constructor
{
    const url = new URL('https://example.com/')
    url.searchParams.set('x', val)

    printTestResults(url.href)
    // `href`: https://example.com/?x=1%26y%3D2
    // ✅ `x` value changed: false
    // ✅ `y` value set: false
}

function printTestResults(href) {
    const url = new URL(href)

    console.info('`href`:', href)
    printExpect('`x` value changed:', url.searchParams.get('x') !== val, false)
    printExpect('`y` value set:', url.searchParams.has('y'), false)
}

function printExpect(msg, result, expect) {
    console.info(result === expect ? '' : '', msg, result)
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
madhan_s profile image
Madhan S

Nice. It is also useful in the case of conditionally adding params like

const url = new URL('http://localhost:3000/endpoint')

url.searchParams.set('param1', var1)
if (condition) {
  url.searchParams.set('param2', var2)
}
url.searchParams.set('param3', var3)
Enter fullscreen mode Exit fullscreen mode

instead of

const url = `http://localhost:3000/endpoint?param1=${var1}${condition ? `&param2=${var2}` : ''}&param3=${var3}`
Enter fullscreen mode Exit fullscreen mode

which becomes messy when adding more parameters

Collapse
 
axorax profile image
Axorax

The URL in the first code block is incorrect. Currently, it is:

const url = `http://localhost:3000/endpoint/param1=${var1}&param2=${var2}&param3=${var3}`
Enter fullscreen mode Exit fullscreen mode

But it should be:

const url = `http://localhost:3000/endpoint?param1=${var1}&param2=${var2}&param3=${var3}
Enter fullscreen mode Exit fullscreen mode

It's missing the ?
Just a small mistake not that big of an issue but I thought I would point it out anyway.

Collapse
 
thdr profile image
Leonardo Theodoro

You are completely right, my bad, I'll fix it.

Collapse
 
vprado-dev profile image
Vinicius Prado

Nice!