0

Say I have a use case for my config file like this:

function generateText(thisIsAVariable) {
  return `This is a sentence with a variable somewhere in the string
${thisIsAVariable} then more string... or not`;
}

I want to be able to import a config file that would transform the above:

import { SENTENCE_CONFIG } = "..."
// SENTENCE_CONFIG.some_sentence {"This is a sentence with a variable somewhere in the string
//[slug] then more string... or not"}


function generateText(thisIsAVariable) {
  return SENTENCE_CONFIG.some_sentence;
  // but have thisIsAVariable plugged in the appropriate "slug" so to speak
}

I know I can make a function to do this, but I want know if there is another way.

bonum_cete
  • 4,730
  • 6
  • 32
  • 56
  • maybe a SENTENCE_CONFIG.some_sntence.replace(slag, thisIsAVariable) ? – Manos Kounelakis Jan 16 '23 at 18:03
  • have a look at this to see how you can use regex for more correct results https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace – Manos Kounelakis Jan 16 '23 at 18:03
  • I don't think this is possible the way you are trying to do it. The biggest give away is the fact that you want the config to call into the javascript code at runtime, which even for a language like JS that threw pretty much all soundness out the window, is extreme. Things like YAML can be parametrized and fetch values dynamically from Vault etc. – sinanspd Jan 16 '23 at 18:09
  • If you want a JS config file, use functions. Otherwise, YAML has variables, or just use any arbitrary templating language. – Bergi Jan 16 '23 at 18:10
  • Secondly, in order to do the actual resolution of `thisIsAVar` which will have different values at different points in the run time without actually passing it to the local scope, you either need full dynamic scope, which is accepted to be one of the biggest mistakes programming history, fluid scopes, or implicits (like Scala), none of which JS has AFAIK. You can somewhat simulate these with `eval` but it isnt recommended. It's just easier to use a function – sinanspd Jan 16 '23 at 18:11

2 Answers2

0

One way to do this is to use a library like mustache.js which is a logic-less template engine. It allows you to replace placeholders in a string with actual data.

// config.js

export const SENTENCE_CONFIG = {
   some_sentence: "This is a sentence with a variable somewhere in the string {{slug}} then more string... or not",
};

// index.js

import { SENTENCE_CONFIG } from "./config";
import Mustache from "mustache";

function generateText(thisIsAVariable) {
   const data = {slug: thisIsAVariable};
   return Mustache.render(SENTENCE_CONFIG.some_sentence, data);
}

Also, the thisIsAVariable would be better if it was an object with all the key:values you want to replace on the config file.

For more info see: https://github.com/janl/mustache.js/

Diogo Peres
  • 1,302
  • 1
  • 11
  • 20
0

You can create a string and add template variables inside of the string. Intentionally NOT using template ticks.

Then have a function that creates an anonymous function that returns a template literal with the string that you pass to it. Then have run call on that function to process the object passed to it.

Then simply pass a string and object of your variables.

This answer is a combination of this answer (https://stackoverflow.com/a/71801207/3684265) and a comment.

let content = {
  "sentence" : "This is your sentence. ${this.thisIsAVariable} and more"
}

function vars(templateString, templateVars) {
    return new Function('return `' + templateString + '`').call(templateVars)
}

function generateText(thisIsAVariable) {
  return vars(content.sentence,{thisIsAVariable});
}

console.log(generateText("TESTT"))
imvain2
  • 15,480
  • 1
  • 16
  • 21