1

I am trying to replace the params of a url with values of an object if the param is the same as a value within the object.

I've got it so that it replaces the values but its just creating an array with 2 items and im looking to basically "merge" them together to create a URL.

Any help is much appreciated!

where urlData consists of something like this which is being passed in:

[
    {
        param: ':userId',
        value: userId || '',
    },
    { param: ':messageId', value: messageId || '' }
]

And my Menu looks like this:

{menu?.map((menuItem, index) => {
    const { title, path } = menuItem
    const finalPath = urlData?.map(
        (url, index) =>
            path.includes(url?.param)
                ? path.replace(
                    url?.param,
                    url?.value
                  )
                : path
        )

    console.log('final', finalPath)

    return (
        <Link
            to={finalPath}
            key={index}
            className={
                pathname === finalPath ||
                finalPath.includes(pathname)
                    ? 'active'
                    : ''
            }
        >
            {title}
        </Link>
    )
})}

My current response:

[
    "/app/messages/be493d77/:messageId",
    "/app/messages/:userId/2cd4df7d"
]

What im looking for:

    "/app/messages/be493d77/2cd4df7d"
4
  • When you map urlData array the result will be an array of equal length. What is the starting value you are trying to replace path segments of? Commented Mar 31, 2022 at 6:49
  • the starting value is /app/messages/:userId/:messageId and id like to replace the params with the values Commented Mar 31, 2022 at 7:00
  • Oh, so you just want to inject the values from the urlData array into the "/app/messages/:userId/:messageId" path string? Commented Mar 31, 2022 at 7:01
  • Yeah, thats correct. Basically if the param is in the path then replace it with the corresponding value in that object. Commented Mar 31, 2022 at 7:02

1 Answer 1

1

Instead of mapping the urlData array which results in an array of equal length, reduce over the array.

Example:

const userId = "be493d77";
const messageId = "2cd4df7d";

const path = "/app/messages/:userId/:messageId";

const urlData = [
  { param: ":userId", value: userId || "" },
  { param: ":messageId", value: messageId || "" }
];

const finalPath = urlData.reduce(
  (path, { param, value }) => path.replace(param, value),
  path
);

console.log(finalPath);

Alternatively you could use the generatePath utility from react-router-dom. This requires the urlData param values to match the param name instead of the path's string literal.

Example:

import { generatePath } from "react-router-dom";

const urlData = [
  { param: "userId", value: userId || "" },
  { param: "messageId", value: messageId || "" }
];

const finalPath = generatePath(
  path,
  urlData.reduce(
    (params, { param, value }) => ({
      ...params,
      [param]: value
    }),
    {}
  )
);
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Drew for the help, very much appreciated. This did the trick! Small oversight at 3:30am...
@Nick No worries, we've all been there. Cheers and good luck!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.