peinearydevelopment peinearydevelopment - 2 months ago 28
TypeScript Question

How can I create a dynamically interpolated string in javascript?

I'm working on creating a reusable UI component and am trying to figure out how to allow the consumer of the component to provide their own template for a particular area of the component.

I'm using typescript and am trying to utilize string interpolation to accomplish this as it seemed the most appropriate course of action.

Here is what I have so far:

export class Pager {
pageNumber: number = 1;

getButtonHtml(buttonContentTemplate?: string, isDisabled?: boolean): string {
buttonContentTemlpate = buttonContentTemplate || '${this.pageNumber}';
isDisabled = isDisabled || false;
return `<button id="button-id" type="button" ${!isDisabled ? '' : disabledAttribute}>
${buttonContentTemplate}
</button>`;
}
}


I have some other methods that will update the page number based off user input/interaction, but I want it to work that when
getButtonHtml
gets called, the return value would be
<button id="button-id" type="button">1</button>
, but instead I'm getting
<button id="button-id" type="button">${this.pageNumber}</button>
.

Is there a way to get javascript to evaluate the string again, and interpolate the remaining place holders?

I've looked at the MDN article on this topic and think that the
String.raw
method might possibly be what I need to use, but I wasn't sure and no matter what I try, I haven't gotten it to work.

Any help would be greatly appreciated.

Answer

The problem is that Template literals are interpreted immediately.

What you want to do is lazy load the template. So it would be best to pass in a function that returns a string.

export class Pager {
    pageNumber: number = 1;

    getButtonHtml(template?: () => string, isDisabled=false): string {
        template = template || function() { return this.pageNumber.toString() };
        return `<button id="button-id" type="button"  ${!isDisabled ? '' : disabledAttribute}>
                    ${template()}
                </button>`;
    }
}

Additionally, you can take advantage of default parameters to avoid the || trick.