DEV Community

Jen C.
Jen C.

Posted on

Efficiently Extract Nested URL Parameters with Recursive Logic in JavaScript

Scenario

Extract the value of a target search parameter (e.g., id) from a nested URL within a URL part, using a given search parameter key (e.g., from).

For example, for the URL /main?from=/details?from=/more?id=456, the function getNestedSearchParamValue extracts the nested URL by looking for the search parameter from.

...

const nestedUrl = new URL(urlPart, dummyUrl);

const nestedUrlPart = nestedUrl.searchParams.get(nestedParamKey) ?? "";

...
Enter fullscreen mode Exit fullscreen mode

First, the nested URL /details?from=/more?id=456 is extracted. Since the URL contains another from search parameter, the getNestedSearchParamValue function calls itself, passing the extracted URL /details?from=/more?id=456 as the urlPart, along with the same nestedParamKey (from) and targetParamKey (id).

...

if(nestedUrlPart.includes(nestedParamKey)){
    return getNestedSearchParamValue(nestedUrlPart, nestedParamKey, targetParamKey);
}

...
Enter fullscreen mode Exit fullscreen mode

In the first recursive call, the nestedUrlPart becomes /more?id=456. Because this URL does not contain the search parameter from (the nestedParamKey), it indicates that this is the target URL to search for the id parameter (the targetParamKey). Therefore, extract the value of the search parameter id from this url part.

...

else {
    const targetUrl = new URL(nestedUrlPart, dummyUrl);
    return targetUrl.searchParams.get(targetParamKey);
}

...
Enter fullscreen mode Exit fullscreen mode

Function

const dummyUrl = "http://localhost";

function getNestedSearchParamValue(urlPart: string, nestedParamKey: string, targetParamKey: string): string | null {
    const nestedUrl = new URL(urlPart, dummyUrl);

    const nestedUrlPart = nestedUrl.searchParams.get(nestedParamKey) ?? "";
    if(!nestedUrlPart){
        return null;
    }
    if(nestedUrlPart.includes(nestedParamKey)){
        return getNestedSearchParamValue(nestedUrlPart, nestedParamKey, targetParamKey);
    }
    else {
        const targetUrl = new URL(nestedUrlPart, dummyUrl);
        return targetUrl.searchParams.get(targetParamKey);
    }
}
Enter fullscreen mode Exit fullscreen mode

Usage

const url = "/main?from=/details?from=/more?id=456";

const value = getNestedSearchParamValue(url, "from", "id");
console.log(value);
Enter fullscreen mode Exit fullscreen mode

Output

[LOG]: "456" 
Enter fullscreen mode Exit fullscreen mode

Alternative: use URLSearchParams

With a helper function getUrlPartSearchParams

const queryDelimiter = "?";

function getUrlPartSearchParams(urlPart: string):URLSearchParams | null {
    const [_, ...query] = urlPart.split(queryDelimiter);
    const queryStr = query.join(queryDelimiter);
    return new URLSearchParams(queryStr);
}
Enter fullscreen mode Exit fullscreen mode

Function getNestedSearchParamValue becomes

function getNestedSearchParamValue(urlPart: string, nestedParamKey: string, targetParamKey: string): string | null {
    let searchParams = getUrlPartSearchParams(urlPart);

    const nestedUrlPart = searchParams?.get(nestedParamKey);
    // console.log(nestedUrlPart)
    if(!nestedUrlPart) {
        return null;
    }
    if (nestedUrlPart.includes(nestedParamKey)) {
        return getNestedSearchParamValue(nestedUrlPart, nestedParamKey, targetParamKey);
    } else {
        searchParams = getUrlPartSearchParams(nestedUrlPart);
        return searchParams?.get(targetParamKey) ?? null;
    }
}
Enter fullscreen mode Exit fullscreen mode

Resources

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay