How to use a predefined interpolation in Javascript

Asked

Viewed 147 times

8

I was reading in ES6 documentation about interpolation (or Template strings) and saw that I can create "escaped templates", as in the example below:

class InvalidParamError extends Error {
  static DEFAULT_MESSAGE = 'Invalid param: ${paramName}.'
  constructor(paramName) {
    super(InvalidParamError.DEFAULT_MESSAGE)
  }
}

The problem is I don’t know how I can use such a template. As far as I know of Javascript interpolation, I would only have two options to work on the fact:

  • Transform property DEFAULT_MESSAGE in a method that receives the message fields;
  • Work with the replace (using regular expressions), in which case the ${paramName} by the field past.

Is there any way (using interpolation) that I can merge the fields with the built message? What I’m looking for is something like the Python interpolation, see in the example below:

DEFAULT_MESSAGE = 'Invalid param: {param_name}'
print(DEFAULT_MESSAGE.format(param_name='foo'))

There is something similar in JS?

1 answer

8


Javascript does not have templates natively. Do not confuse strings template with a "real template", which can be "evaluated" later - as the function format python makes.

As strings template of Javascript allow the interpolation of values. Think of an alternative to concatenation. Thus, you accurate have all the values you want to interpolate when the string template be evaluated.

Note also that strings template are denoted with the sign of the severe accent (`), and not with single quotes (') or doubles ("). This is why you are not getting an error in your example. In your example, you did not use strings template. Used only "normal strings". See the error you would get if you were trying to interpolate a value that is not available at the time of evaluation:

class InvalidParamError extends Error {
  // ❗️ Uncaught ReferenceError: paramName is not defined
  static DEFAULT_MESSAGE = `Invalid param: ${paramName}.`;
  
  constructor(paramName) {
    super(InvalidParamError.DEFAULT_MESSAGE);
  }
}

The error occurred because strings template is not a template real (usually templates allow later evaluation). As we have seen, strings template, in Javascript, they are nothing more than a mere different name for interpolation of strings. Alone, the strings template do not allow further evaluation. Thus, you are thank you to provide the values to be interposed when the string template is assessed by Runtime of Javascript. Otherwise, a ReferenceError will be released.

In your example, no error occurred because the string used (denoted with single quotes) did not evaluate paramName (a reference that at that time could not be found).

If you want to "emulate" the behavior of a template, you can create a function to make the string "Lazy", that is, lazy. Thus, we will evaluate it only in possession of paramName:

class InvalidParamError extends Error {
  static DEFAULT_MESSAGE = (paramName) =>
    `Invalid param: ${paramName}.`;
  
  constructor(paramName) {
    super(InvalidParamError.DEFAULT_MESSAGE(paramName));
  }
}

console.log(new InvalidParamError('Foo').message); // `Invalid param: Foo.`

Note that in this case it makes no difference to use strings template (interpolation) or a mere concatenation:

class InvalidParamError extends Error {
  static DEFAULT_MESSAGE = (paramName) =>
    'Invalid param: ' + paramName + '.';
  
  constructor(paramName) {
    super(InvalidParamError.DEFAULT_MESSAGE(paramName));
  }
}

console.log(new InvalidParamError('Foo').message); // `Invalid param: Foo.`

However, in that case, I do not believe that DEFAULT_MESSAGE "Lazy", turning it into a method, be really beneficial. The benefit of this, in this case, is almost nil.

Nothing prevents you from evaluating the string directly in the manufacturer, which is, in this case, much simpler:

class InvalidParamError extends Error {
  constructor(paramName) {
    super(`Invalid param: ${paramName}.`);
  }
}

console.log(new InvalidParamError('Foo').message); // `Invalid param: Foo.`

In short, to make the evaluation of string template (interpolation) Lazy, what we did was basically create a static method (using the notation of Arrow functions), as suggested in the question itself. Another option, also suggested, is to use regular expressions to do the replace.

Finally, as I always say, another example of how it is possible to do various things in programming. Evaluate the costs of each option and do as you prefer. :)

  • The intention to create a DEFAULT_MESSAGE is that I can "mock" and test error messages without relying on having the error already built. can then compare them. I have a string with simple quotes as an example, and I already know that it would be possible to use as a function, so much that I already put in the question. So I asked, if there was another way to do it.

  • 5

    @Leandroluk, then, in my opinion, postpone the evaluation of string template (make it "Lazy"), that is, transform it into a method, seems to me to be the most ideal. : ) Using a library of templates or even regular expressions in cases like this seems to me

  • 4

    Speaking of shooting ants with bazooka, look what I found: https://www.npmjs.com/package/python-format

Browser other questions tagged

You are not signed in. Login or sign up in order to post.