0

I have a map like so:

const urlPaths = {
        "Signature": "signature/(signatureId)",
        "Rule": "signature/(signatureId)/rule/(ruleId)",
    };

I then have some data that comes in my API like:

aId: {
    signatureId: "999"
}

or

aId: {
    signatureId: "123",
    ruleId: "456"
}

I want to be able to use that map, to return me the url for Signature or Rule, for example:

"signature/999" or "signature/123/rule/456"

I've come across the regex replace, but wondering, can I actually use that in this case?

function createUrl(url, regex, aId){
   url.replace(regex,(id) => aId[id])
}

Not sure if its possible/how to do with that or do I need something else?

Any ideas appreciated.

Thanks.

2 Answers 2

1

Not sure that a RegExp is strictly necessary, since the patterns you want to replace match the names of your properties. You could do something like this:

const urlPaths = {
  "Signature": "signature/(signatureId)",
  "Rule": "signature/(signatureId)/rule/(ruleId)",
};

const aId1 = {
    signatureId: "999"
};

const aId2 = {
  signatureId: "123",
  ruleId: "456"
};

const createUrl = (url, aId) => {
  let newUrl = url;
  Object.entries(aId).forEach(([key, value]) => {
    newUrl = newUrl.replace(`(${key})`, value);
  });
  return newUrl;
}

console.log(createUrl(urlPaths.Signature, aId1));
console.log(createUrl(urlPaths.Rule, aId2));

If you do want to use a RegExp though, here's an example of how that could work too

const urlPaths = {
  "Signature": "signature/(signatureId)",
  "Rule": "signature/(signatureId)/rule/(ruleId)",
};

const aId1 = {
    signatureId: "999"
};

const aId2 = {
  signatureId: "123",
  ruleId: "456"
};

const createUrlRegExp = (url, regexs, aId) => {
  let newUrl = url;
  const replacer = match => aId[match.slice(1, -1)]; // get rid of parentheses around match
  regexs.forEach(regex => {
    newUrl = newUrl.replace(regex, replacer)
  });
  return newUrl;
};

console.log(createUrlRegExp(urlPaths.Signature, [/\(signatureId\)/], aId1));
console.log(createUrlRegExp(urlPaths.Rule, [/\(signatureId\)/, /\(ruleId\)/], aId2));

Sign up to request clarification or add additional context in comments.

Comments

1

As the poster asks for a Typescript solution, here I'm providing a Typescript solution. You don't necessarily need for regexp here, as the string.replace accepts a string as a pattern also.

interface AID {
  signatureId: string,
}

interface AIDWithRuleId extends AID {
  signatureId: string,
  ruleId: string,
}

interface UrlPaths {
  Signature: string,
    Rule: string,
}

enum ValuesToReplace {
  signatureId = '(signatureId)',
    ruleId = '(ruleId)'
}

class URLBuilder {
  private static urlPaths: UrlPaths = {
    Signature: `signature/${ValuesToReplace.signatureId}`, // or you can keep "signature/(signatureId)"
    Rule: `signature/${ValuesToReplace.signatureId}/rule/${ValuesToReplace.ruleId}`, // or you can keep "signature/(signatureId)/rule/(ruleId)"
  }


  static getSignatureUrl(data: AID): string {
    return this.urlPaths.Signature.replace(ValuesToReplace.signatureId, data.signatureId);
  }

  static getRuleUrl(data: AIDWithRuleId): string {
    return this.urlPaths.Rule
      .replace(ValuesToReplace.signatureId, data.signatureId)
      .replace(ValuesToReplace.ruleId, data.ruleId);
  }

}

let x1: AID = {
  signatureId: '1'
};
let x2: AIDWithRuleId = {
  signatureId: '1',
  ruleId: '1'
};

console.log(URLBuilder.getSignatureUrl(x1));
console.log(URLBuilder.getRuleUrl(x2));
console.log(URLBuilder.getSignatureUrl(x2));

1 Comment

I just stuck with the syntax OP used, assuming that they don't have many strict compiler flags enabled, but good point

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.