0

I have the list of document elements. I want to change elements’ outerHtml with html. HTML is loaded from files in cycle, so I use promises. The problem is with passing the element to promise function in the cycle, because only the last element from array is passed.

 ...
 /**
 * Set outer html of element.
 * @param element
 * @param newHtml
 */
setOuterHtml = function(element, newHtml){    
    console.log("ELEMENT ", element); // always <ge-test-2></ge-test-2>
    element.outerHTML = newHtml;
}

this.loadElementsToHtml = function(){
    console.log(this.elements); 
    //[ge-survey, ge-test-1, ge-test-2]
    var promises  = [];
    for(var i=0; i<this.elements.length; i++){
        var el = this.elements[i];
        // laod html from file
        var elPromise = this.loadHtml(el);
        // set outer html when HTML is loaded
        //// problem here with el !!! always ge-test-2 element
        elPromise.then(res => setOuterHtml(el,res)); 
        promises.push(elPromise);
    }

    return Promise.all(promises);
}
Tim Grant
  • 3,300
  • 4
  • 23
  • 31
Edgaras Karka
  • 7,400
  • 15
  • 61
  • 115
  • Possible duplicate of [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – melpomene Dec 04 '16 at 13:22

2 Answers2

1

It looks like the problem here is that the el variable is changing as you loop through the elements, and when the loop is done, el will refer to the last element in the array.

A simple (and cleaner) way to do this correctly is to use .map() so that each iteration gets its own scope:

this.loadElementsToHtml = function(){
    console.log(this.elements); 
    //[ge-survey, ge-test-1, ge-test-2]

    return Promise.all(this.elements.map(el => 
        this.loadHtml(el).then(res => setOuterHtml(el, res));
    ));
}
JLRishe
  • 99,490
  • 19
  • 131
  • 169
-2

You seem to already have the element inside this.elements, just pass that one on with its index.

this.loadElementsToHtml = function(){
    console.log(this.elements); 
    var promises  = [];
    for(var i=0; i<this.elements.length; i++){
        // laod html from file
        var elPromise = this.loadHtml(this.elements[i]);
        elPromise.then(res => setOuterHtml(this.elements[i], res)); 
        promises.push(elPromise);
    }

    return Promise.all(promises);
}
casraf
  • 21,085
  • 9
  • 56
  • 91