1

I have a task to replace all keys in string pattern with their values. The input is something like that:

[
  '{ "name": "John", "age": 13 }',
  "My name is #{name} and I am #{age}-years-old"
]

And the output is this: 'My name is John and I am 13-years-old'.
So I come up with this:

function FillTemplate() {
if (arguments.length < 2 || arguments.length > 7) {
    console.log('The input objects should be at least 1 and lesser than 7!');
}

for (let i = 0; i <= arguments.length - 2; i += 1) {
    JSON.parse(arguments[i]);

     for (let j = 0; j < Object.keys(arguments[i]).length; i += 1) {
         let currentKey = Object.keys(arguments[i])[j];
         console.log(currentKey);
     }
}
}

I have a problem when i console.log(currentKey) i got only zeros but my idea is take the first object in the input then json.parse it next take all the keys in that object and with one loop take every single key separately and replace it in the pattern string with regex pattern. But this Object.keys return only zeros to me. Where is the problem?

4
  • 1
    can you simulate it in jsfiddle? Commented Feb 10, 2017 at 10:14
  • I'm not really getting what you intend to do. Commented Feb 10, 2017 at 10:16
  • Excuse me the output is not zeros. It is numbers from '1' to '28'. And my intention is to take all keys from an object and tryna replace them in the string pattern with their values. Commented Feb 10, 2017 at 10:18
  • When i run it with FillTemplate('{ "name": "John", "age": 13 }', 'My name is #{name} and I am #{age}-years-old'); this #{name} and #{age} should be John and 13. In my example Object.keys(arguments[i]) should contain [ 'name', 'age' ] but it contains [1..28] Commented Feb 10, 2017 at 10:21

2 Answers 2

2

Here you go:

<script>
var foo = {
    "name" : "John",
    "age"  : 13
}
var string = "My name is #{name} and I am #{age}-years-old";

// Extract all templates (#{name}, #{age}, ...)
var matches = string.match(/#{[a-zA-Z]+?}/g);
if ( matches ) {
    matches.forEach(function(templateStringToReplace) {
        // Strip the special characters to dynamically get the indices of the object
        templateString = templateStringToReplace.replace(/#|{|}/g, "");
        string = string.replace(templateStringToReplace, foo[templateString])
    });
}

alert(string);

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

Comments

0

Try the other way around, parse the template string first, then loop over the keys you need so you can reference them directly in the object. Also, I have no idea what you're trying to do with the arguments object.

    // Our source array containing a data string and a template string
var source = [
        '{"name": "John", "age": 13 }',
        'My name is #{name} and I am #{age}-years-old'
    ],
    // helper function to grab all the parameters from a template string
    parseTemplate = function parseTemplate( template ) {
        var regex = /#\{(.+?)\}/g,
            parameters = [],
            nextParameter;
        do {
            // this regexp will grab the next series of characters surrounded by #{}
            nextParameter = regex.exec(template);
            if (nextParameter) parameters.push(nextParameter[1]);
        }
        // as long as there are parameters left, keep searching
        while (nextParameter);
        return parameters;
    },
    // population function, uses parseTemplate to get the parameters and then adds them to the template
    populateTemplate = function populate( template, data ) {
        var parametersToSaturate = parseTemplate(template);
        // for each parameter found, repalce that parameter in the string with the value from the data
        return parametersToSaturate.reduce(function( saturatedTemplate, parameter ) {
            return saturatedTemplate.replace('#{' + parameter + '}', data[parameter] || ('#{' + parameter + '}'));
        }, template);
    },
    result = populateTemplate( source[1], JSON.parse(source[0]) );
console.log(result);

As long as you keep the array returned from parseTemplate is the same order, you can reuse any parameter as many times in a string as you want. Any #{val} parameter not found in the data will just remain.

If you have multiple objects, you can just loop over them.

sources.forEach(function( source ) {
    console.log(populateTemplate( source[1], JSON.parse(source[0]) ));
});

If your browser supports it, you can use actual JS template strings: https://developer.mozilla.org/nl/docs/Web/JavaScript/Reference/Template_literals

Comments

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.