1
votes

I have the following Vue template:

<div v-for="cartItem in cartItems">
    <p class="is-size-5 has-text-weight-bold" v-if="showCategoryName(cartItem.searchCat2)">
        {{cartItem.searchCat2}}
    </p>
</div>

Which is calling the following Vue method

showCategoryName(catName) {
  if (this.currentCatName === catName) {
    return false;
  }
  this.currentCatName = catName;
  return true;
},

This causes the following Vue Warning in the console:

You may have an infinite update loop in a component render function.

As you can see by the code, although there is assignment in the loop, there is nothing about this assignment that will cause infinite updates.

I have also tried replacing {{cartItem.searchCat2}} with {{currentCatName}} but I still receive the error.

How can I either suppress this error, or make Vue satisfied that there is no infinite update loop possible?

Update:

What this code accomplishes for me is that, because cart items are grouped by category name, only the first item with that category name displays the category name. So instead of every product of the chair category having "Chair" displayed above it, only the first does. This works as I expect it to.

1
Changing state inside a template is kind of strange. What does showCategoryName do by setting currentCatName? (Template rendering should be idempotent...) - Ry-
What's the purpose of that assign? When it's first checked, you return true, but then you change it to false? In the end you would show nothing? - dziraf
Try hoisting the logic of the v-if into some map()ed version of cartItems. That way you are doing as little logic within the v-for as possible. - zero298
@Ry- Basically, cart items are grouped by category name, and only the first item with that category name should display the category name. Instead of every chair product having "Chair" above it, only the first does. - Goose
Wouldn't it be easier to create a computed property that splits your source array into category-grouped sub-arrays like here: jsfiddle.net/eywraw8t/24880 ? - dziraf

1 Answers

2
votes

You can refer to the previous item directly in the template by index:

<div v-for="(cartItem, index) in cartItems">
    <p class="is-size-5 has-text-weight-bold"
       v-if="index === 0
             || cartItem.searchCat2 !== cartItems[index - 1].searchCat2">
        {{cartItem.searchCat2}}
    </p>
</div>