SteinTech
SteinTech

Reputation: 4068

iterating through an array containing two elements results in three objects

I'm trying to iterate through an array and clone and append an element to a div element for each item in the array. Everything is working except when it's more than one element I get some unexpected results. The array contains two element's and I've checked that the each loop only runs two times, but for some reason I get a third element in the result.

Am I using clone() and appendTo() correctly?

enter image description here

each loop:

let items = $(contentWrap).find(".lc-rating-modal-review-items-wrap");
$(items).empty();

$.each(data.items, function (index, review) {
    let item = GenerateReviewItem(review);
    $(item).appendTo(items);
});

GenerateReviewItem:

function GenerateReviewItem(review) {
    let result = $(wrap).find(".lc-rating-review-item-template").clone();

    $(result).find(".lc-rating-review-item-template-date").html(review.dateFormated);
    $(result).find(".lc-rating-review-item-body-wrap").html(review.review);
    $(result).find(".lc-rating-review-item-template-stars-rating-label").html("(" + review.rating + ")");

    $(result).find(".lc-rating-review-item-template-star").each(function (index, star) {
        if (review.rating >= (index + 1)) {
            $(star).removeClass("fa-star-o").addClass("fa-star");
        }
    });              

    return result;
}

Html to clone:

<div style="display:none;">
    <div class="lc-rating-review-item-template">
        <div class="lc-rating-review-item-header-wrap">
            <div class="lc-rating-review-item-template-stars-wrap">
                <div>
                    <i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
                </div>
                <div>
                    <i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
                </div>
                <div>
                    <i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
                </div>
                <div>
                    <i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
                </div>
                <div>
                    <i class="fa fa-star-o lc-rating-review-item-template-star" aria-hidden="true"></i>
                </div>
                <div>
                    <span class="lc-rating-review-item-template-stars-rating-label"></span>
                </div>
            </div>
            <div style="text-align:right;">
                <span class="lc-rating-review-item-template-date"></span>
            </div>
        </div>
        <div class="lc-rating-review-item-body-wrap"></div>
    </div>
</div>

Upvotes: 0

Views: 65

Answers (1)

Michael Sacket
Michael Sacket

Reputation: 907

I'd recommend storing the reference to your template node outside of your loop, and then doing the cloning inside of the loop.

Define this outside the loop:

let template = $(wrap).find(".lc-rating-review-item-template")

And then change this:

let result = $(wrap).find(".lc-rating-review-item-template").clone();

To this:

let result = template.clone();


As it is currently, when your loop executes a second time, $(wrap).find(".lc-rating-review-item-template") is likely finding two items instead of one.

It also appears that wrap, unless it is a global, is undefined within the context of the GenerateReviewItem(review) function.

Upvotes: 1

Related Questions