2

I am creating functions containing strings that need interpolation:

let createPFunc = (string) => {
    return () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(`${string}`);
                resolve();
            }, 2000);
        })
    }
}
let f1 = createPFunc('String 1: ${string}');
let f2 = createPFunc('String 2: `${string}`');

f1(`search 1`).then(() => f2('search 2'))

What it prints is:

String 1: ${string}
String 2: `${string}`

I want it to print:

String 1: search 1
String 2: search 2

I tried different quoting variations, but can't find a combination that works.

How can I perform interpolation twice, or delay interpolation so ${string} is resolved when the function is called (instead of when the function is created)?

Rodrigo Rodrigues
  • 7,545
  • 1
  • 24
  • 36
tmillan
  • 21
  • 1
  • Why are you using promises here? What is the point of `createPFunc`? Why not just write ``const f1 = string => `String 1: ${string}`;``? – Bergi Jun 22 '21 at 22:07
  • "*How can I perform interpolation twice*" - you cannot. See also https://stackoverflow.com/questions/22607806/defer-execution-for-es6-template-literals – Bergi Jun 22 '21 at 22:08
  • Take a look at this: https://stackoverflow.com/questions/30003353/can-es6-template-literals-be-substituted-at-runtime-or-reused/54124803#54124803 – Rodrigo Rodrigues Jun 22 '21 at 22:09

1 Answers1

1

Take a look at this answer in another question to find details on how to defer the substitution of a string interpolation. I am using the defer function here for that.

You can achieve what you want by doing this:

    function defer([first, ...rest]) {
        return (...values) => rest.reduce((acc, str, i) => acc + values[i] + str, first);
    }
    
    var createPFunc = (template) => {
        return (string) => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log(template(string));
                    resolve();
                }, 2000);
            })
        }
    }
    
    var f1 = createPFunc(defer`String 1: ${'string'}`);
    var f2 = createPFunc(defer`String 2: ${'string'}`);
    
    f1(`search 1`).then(() => f2('search 2'))
    // result:
    // String 1: search 1
    // String 2: search 2
Rodrigo Rodrigues
  • 7,545
  • 1
  • 24
  • 36
  • Using `'string'` as an interpolated value is confusing, since it's just ignored - the value has no significance. Better avoid that `defer` tag and just write ``createPFunc(string => `String 1: ${string}`)``. – Bergi Jun 22 '21 at 22:23
  • That is right, the argument is ignored in this case. It could easily be `null` or `undefined` (but needs to pass something, because of the syntax of es6 templates). I used the word string to make it more alike OP's original code, but yeah, that might confuse someone. – Rodrigo Rodrigues Jun 22 '21 at 22:29