Setting Path Variables in Pre-request Script

This is a follow-up to this post from December. I have been using this implementation in a Postman web app collection for the past month or so, but at some point in the last week it stopped working.

Now when I make a request using the solution in the link above, I get

There was an error in evaluating the Pre-request Script:TypeError: pm.request.url.toJSON is not a function

Is this a recent/intended change in Postman to disallow this method of accessing the request path variables? If so, what is the new strategy to accomplish this functionality?

I wish I could just go with the “replace path variable with {{variable}} in request” route, but we’re using a collection from a 3rd party for their API that has hundreds of requests, all with the same 1-2 path variables. I can export the collection and edit the JSON file to switch things over, but that’s not a great solution for my team—a prerequest script is a much better solution as its easier to setup.

1 Like

Hey @lunar-module-opera10 :waving_hand:

Welcome to the Postman Community! :postman:

Would you be able to share more details about the URL and the full pre-request script you are using that causes the error, please?

You can mask all the sensitive data, we just need to see the structure of the URL and the code in the script. :folded_hands:

Hey, Danny! Here’s the script I’m using:

// automatically set API Version
const version = pm.collectionVariables.get("apiVersion");
pm.request.headers.upsert({ key: "X-Gusto-API-Version", value: version });

// helper method for automatically managing paths
const setPathVariableIfPresent = (key, value) => {
    const url = pm.request.url.toJSON();
    const index = url.variable.findIndex(item => item.key === key);
    if (index >= 0) {
        url.variable[index].value = value;
        pm.request.url = url;
    }
}

// check to see if the request is overriding these settings
const override = pm.request.url.query.all().some(param => param.key === 'override');
if (!override) {
    // set company id on relevant requests based on current environment 
    const companyId = pm.environment.get("gusto_company_id");
    if (companyId) setPathVariableIfPresent("company_id", companyId);

    // set employee id on relevant requests based on current environment 
    const employeeId = pm.environment.get("gusto_employee_id");
    if (companyId) setPathVariableIfPresent("employee_id", employeeId);
    }
}

These are my environment and collection variables, respectively:


Here’s what the request looks like (the goal was to setup a pre-request script that would automatically populate the employee_id and company_id path variables if they are present):

Bizarrely, though, I am seeing this morning that my employee endpoint seems to work

1 Like

How does the override param fit into the URLs being run?

Is that something that you either add or don’t add manually?

For the request that was working this morning, does that append everything correctly to the URL? I can’t tell as I don’t see the console output for the request.

It’s a way for a user to bypass the automatic path variable settings in the script so they can use hard-coded values in the request like this:

1 Like

Yeah I’m super confused now because the employee endpoint is returning a 404 again (not throwing the Javascript error), and it’s just not replacing the path variable value now.

So for the employee, it looks like I was actually checking the companyId on the if statement :woman_facepalming:

After fixing that, I’m getting 404s for both as it’s not changing the path variable in either now.

From that line in the code, it’s still going to be true if it’s there but it’s been disabled, right? It would only be false if it’s completely removed.

This doesn’t mean anything for the overall problem you’re facing, I was just trying to get that clear in my mind.

When it’s disabled, it’s not added to the request string at all:

Ah it looks like there might be a new method of changing the variables. This seems to work :woman_shrugging:

const setPathVariableIfPresent = (key, value) => {
    const variables = pm.request.url.variables;
    if (!variables) return;

    const variable = variables.find(v => v.key === key);
    if (variable) {
        variable.value = value;
    }
}

It’s still true as per that script though.

Param enabled:

Param disabled:

Param removed:

Ah yeah, it looks like I need to update my override check to this:

const override = pm.request.url.query.find(param => param.key === 'override');
if (!override || override.disabled) {
 // settings
}

The previous script I posted clears up the “not a function” error I was getting, so now everything appears to be working as expected :grin:

1 Like

Awesome! Glad to see you have it all working! :trophy: