AJW
AJW

Reputation: 5863

vuejs if/else: check if element exsists else add a element

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.

Upvotes: 1

Views: 122

Answers (3)

Felix Contreras
Felix Contreras

Reputation: 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>

Upvotes: -1

skirtle
skirtle

Reputation: 29092

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>

Upvotes: 1

The Fool
The Fool

Reputation: 20430

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>

Upvotes: 2

Related Questions