Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

651
Views
How to use v-if, v-else inside of v-for properly in Vuejs?

<template>
  <div>
    <div v-for="box in boxes" :key="box.id">
      <BaseAccordian>
        <template v-slot:title>{{ box.name }}</template>
        <template v-slot:content>
          <div v-for="paint in paints" :key="paint.id" class="line">
            <div
              v-if="
                matchingdata.some(
                  (m) => m.boxid == box.boxid && m.paintid == paint.paintid
                )
              "
            >
              <StatusComponent
                :box="box"
                :paint="paint"
                :matchingdata="matchingdata"
              />
            </div>
            <!-- <div v-else>no data found</div> -->
          </div>
        </template>
      </BaseAccordian>
    </div>
  </div>
</template>

When i click of each checkbox, i am loading relevant data from box,paint array. by checking in matchingdata. Array.

Now, i want to show like, if no data found onclick of checkbox, i want to display a message as "no data found"

Issue with the below code is, if i place v-if at top and v-for and v-else data at the last then only few data is displaying

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

the v-if checking ok and not ok should be written before the outside for loop
(before this row <div v-for="paint in paints" :key="paint.id" class="line">)
so the whole code should be somthing like this :

    <div v-if="your data existence checking ....."> 
   <div v-for="paint in paints" :key="paint.id" class="line">
            <div
              v-if="
                matchingdata.some(
                  (m) => m.boxid == box.boxid && m.paintid == paint.paintid
                )
              "
            >
              <StatusComponent
                :box="box"
                :paint="paint"
                :matchingdata="matchingdata"
              />
            </div>
          </div>
         </div>
<div v-else>no data found</div> 
over 4 years ago · Santiago Trujillo Report

0

Use matchingdata.some() again

You can use matchingdata.some() in a v-if above the v-for loop, which checks if any of the paints can be found. Put a v-else at the bottom with your text.

See fix below:

<template>
  <div>
    <div v-for="box in boxes" :key="box.id">
      <BaseAccordian>
        <template v-slot:title>{{ box.name }}</template>
        <template v-slot:content>
          <template v-if="
              matchingdata.some(
                (m) => m.boxid == box.boxid && paints.find( (paint) => m.paintid == paint.paintid )
              )
            "
          >
            <div v-for="paint in paints" :key="paint.id" class="line">
              <div
                v-if="
                  matchingdata.some(
                    (m) => m.boxid == box.boxid && m.paintid == paint.paintid
                  )
                "
              >
                <StatusComponent
                  :box="box"
                  :paint="paint"
                  :matchingdata="matchingdata"
                />
              </div>
            </div>
          </template>
          <div v-else>no data found</div>
        </template>
      </BaseAccordian>
    </div>
  </div>
</template>

I pasted this into your code sandbox and it made the message only appear once per box.

The relevant piece is checking all paints beforehand with paints.find:

matchingdata.some(
  (m) => m.boxid == box.boxid && paints.find( (paint) => m.paintid == paint.paintid )
)

Documentation:

  • Array.prototype.some
  • Array.prototype.find
over 4 years ago · Santiago Trujillo Report

0

The v-for is rendering for each 'box' in 'boxes', so for each box you should get a:

<BaseAccordian>
  <template v-slot:title>{{ box.name }}</template>
  <template v-slot:content>
    <div v-for="paint in paints" :key="paint.id" class="line">
 {...}
    </div>
  </template>
</BaseAccordian>

And for each paint in paints, this should render a div for each paint inside of every box.

The v-if and v-else-if and v-else will render their blocks conditionally on the predicates contained within them. I'm not sure where the array matchingdata comes from in your example, but if it contains an element that has the properties boxid and paintid that match box.boxid and paint.paintid then the predicate of matchingdata.some((m) => m.boxid == box.boxid && m.paintid == paint.paintid) will have been met and the associated div will be rendered; otherwise, the 'v-else' div will be rendered (if it were uncommented).

Your code will loop through each box in boxes, and for each box it will loop through each paint in paints to find an element in matchingdata that looks something like:

{
  boxid: ...,
  paintid: ...,
  ...,
}

The v-for and (v-if, v-else-if, v-else) blocks are not connected to each other. v-for represents a loop over which you will render an element for every item in the list. The v-if blocks will conditionally render elements to the page according to the predicates you define.

v-if, v-else-if, and v-else have to appear right after each other to be counted in the same logical block.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!