27

I am trying to use a v-if statement to show some HTML only if the archiveNote variable is not empty/null.

<div v-if="archiveNote === null || archiveNote ===''" class="form-check ml-3" id="include-note-div">

Here is how it's instantiated

export default {
    name: "ConfirmReleaseFilesModal",
    props: {
        archiveName: String,
        archiveNote: String
    },

which is then passed in from this other Vue file

<confirm-release-files-modal
    v-if="showConfirmReleaseFilesModal"
    @cancel="closeModal"
    @confirmAndEmail="releaseAction"
    @confirmNoEmail="releaseAction"
    :archive-name="archiveName"
    :archive-note ="archiveNote"
>
</confirm-release-files-modal>

The block of HTML still shows when archiveNote is console.log out as empty

Dan
  • 59,490
  • 13
  • 101
  • 110
d1596
  • 1,187
  • 3
  • 11
  • 25

2 Answers2

56

If you want to show the <div> only when it is truthy (not empty/null/etc.), you can simply do:

<div v-if="archiveNote">

This gives the same result as the double bang:

<div v-if="!!archiveNote">

Both of these expressions evaluate all 8 of JavaScript's falsy values to false:

  • false
  • null
  • undefined
  • 0
  • -0
  • NaN
  • ''
  • 0n (BigInt)

and everything else to true. So if your variable evaluates to anything but these it will be truthy, and the v-if will show.

Here's a demo of these and some truthy examples:

new Vue({
  el: "#app",
  data() {
    return {
      falsy: {
        'null': null,
        'undefined': undefined,
        '0': 0,
        '-0': -0,
        '\'\'': '',
        'NaN': NaN,
        'false': false,
        '0n': 0n
      },
      truthy: {
        '[]': [],
        '{}': {},
        '\'0\'': '0',
        '1': 1,
        '-1': -1,
        '\' \'': ' ',
        '\'false\'': 'false',
        '5': 5
      }
    }
  }
});
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}
#falsy, #truthy {
  display: inline-block;
  width: 49%;
}
.label {
  display: inline-block;
  width: 80px;
  text-align: right;
}
code {
  background: #dddddd;
  margin: 0 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div id="falsy">
    Falsy:
    <div v-for="(test, label) in falsy">
      <div class="label">{{ label }}</div>
      <code v-if="test">true</code>
      <code v-else>false</code>
    </div>
  </div>
  
  <div id="truthy">
    Truthy examples:
    <div v-for="(test, label) in truthy">
      <div class="label">{{ label }}</div>
      <code v-if="test">true</code>
      <code v-else>false</code>
    </div>
  </div>
</div>
Dan
  • 59,490
  • 13
  • 101
  • 110
0

It might be caused by the fact that in the parent component you are assigning your variables to incorrectly named props :archive-name="archiveName" instead of :archiveName="archiveName".

depperm
  • 10,606
  • 4
  • 43
  • 67
Eggon
  • 2,032
  • 2
  • 19
  • 38
  • 1
    this doesn't seem to be the case [doc](https://vuejs.org/v2/guide/components-props.html#Prop-Casing-camelCase-vs-kebab-case) – depperm Mar 20 '20 at 18:24