1

I have a v-for like so:

            <p> User Responses(s):</p>
        <template v-for="item in UserResponses">
          <ol v-if="item.some_condition==item._is_true">
            <li :name="item.id + '__UR'"> [[ item.some_variable_to_render ] ]] </li>
          </ol>
      </template>

Works great. However, what I would like to do is say No user responses when the some_condition_is_true fails, but if I add an v-else the message (No user responses) will be printed in every loop, which is not desired ofcourse. How does one solve this problem?

To this end, I wondered if I could test if the element item.id + '__UR'" is present and if not add an element with text sayingNo user responses`

I am not sure however that this is the correct way to go about this.

EDIT

Just to reiterate: using v-if before v-for is not an option since the object being iterated on is a nesed JSON which then is filtered through some vuejs filters, so yea, this is not an option.

7
  • Use v-if in the same <template> element along your v-for? Commented Jan 1, 2020 at 14:40
  • @kerbholz: that is not the recommended way to do it according to docs. I am not even sure how that would work. Can you show some code please? Commented Jan 1, 2020 at 14:42
  • why dont you use a v-else? Commented Jan 1, 2020 at 14:50
  • 1
    If there are no user responses, there should be no rendered templates. Can you simply have a second template with v-if="UserResponses.length"? Commented Jan 1, 2020 at 14:51
  • Right, missed that, sorry. On that same guide page there's an example of how to do it right though: Place your v-if outside of your v-for loop Commented Jan 1, 2020 at 14:51

3 Answers 3

2

note that boolVar corresponds to your actual object key that contains the bools


let model.flag = true

function foo(val) => {
  model.flag = val
  return val
}

<p> User Responses(s):</p>
<template>
  <div v-if="model.flag">
    <div v-for="item in UserResponses"   >
      <ol v-if="foo(item.Boolvar)" >
        <li :name="item.id + '__UR'"> [[ item.some_variable_to_render ] ]] </li>
      </ol>
    </div>
  </div>
  <h1 v-else>No user responses 😢</h1>
</template>
Sign up to request clarification or add additional context in comments.

19 Comments

Hmm.. I cant do this because the v-if depends on the item being irterated on - I have now made this clear by editing the post.
so you say there can be items in the list but the items are kinda null?
Hmm.. well. wouldnt h1 appear in every loop? Isnt that the problem with this approach?
that is why you have an else statement right? if true do this else do that. So no not both things happen
I added a third version that keeps the list intact
|
1

It is possible you may be able to implement this using CSS:

ol + .no-responses {
  display: none;
}

There's a full example below but the idea is simply to hide the message if it comes after an <ol>. Tweak the selector to reflect your real use case.

I have tried to keep the template in my example exactly the same as the original code, with the addition of the relevant message and a couple of buttons for demo purposes.

new Vue({
  el: '#app',
  delimiters: ['[[', ']]'],
  
  data () {
    return {
      UserResponses: []
    }
  },
  
  methods: {
    add () {
      this.UserResponses.push(
        { some_condition: 3, _is_true: 3, id: 3, some_variable_to_render: 'A' },
        { some_condition: 3, _is_true: 4, id: 4, some_variable_to_render: 'B' },
        { some_condition: 4, _is_true: 4, id: 5, some_variable_to_render: 'C' },
        { some_condition: 5, _is_true: 5, id: 6, some_variable_to_render: 'D' }
      )
    },
    
    clear () {
      this.UserResponses.splice(0)
    }
  }
})
ol + .no-responses {
  display: none;
}
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>

<div id="app">
  <p>User Responses(s):</p>
  <template v-for="item in UserResponses">
    <ol v-if="item.some_condition==item._is_true">
      <li :name="item.id + '__UR'"> [[ item.some_variable_to_render ]] </li>
    </ol>
  </template>
  <p class="no-responses">No user responses</p>
  <button @click="add">Add values</button>
  <button @click="clear">Clear values</button>
</div>

Comments

-1

Using computed with v-if: • Sometimes, you might have a list of items that you want to filter based on a condition and then render the filtered list using v-if. In such cases, instead of putting the filtering logic directly in the template with v-if, you can use a computed property to create a filtered version of the list https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.

• This approach separates the concerns of data processing and rendering, making the code more maintainable and potentially improving performance since the filtered list is only re-computed when the original list or the filter condition changes.

Here's an example of using a computed property with v-if:

<template>
<div>
<ul>
<!-- Use v-if to conditionally render items based on the computed property -->
<li v-for="item in filteredList" v-if="item.isVisible">
{{ item.name }}
</li>
</ul>
</div>
</template>

<script>
export default {
data() {
return {
items: [
{ name: 'Item 1', isVisible: true },
{ name: 'Item 2', isVisible: false },
// ... more items
],
};
},
computed: {
// Create a computed property for the filtered list
filteredList() {
return this.items.filter(item => item.isVisible);
},
},
};
</script>

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.