I am encountering issues in Vue JS when using ternary expressions alongside v-if statements

Snippet:-

<template>
  <div id="calendars-results">
    <div class="vs-con-loading__container">
      <div class="vs-row flex justify-between">
        <h4 class="vs-row mb-2">{{ title }}</h4>
        
        <date-picker
          v-if="date"
          class="vs-row"
          v-model="date"
          type="date"
          placeholder="Select Date"
          valueType="format"
          format="YYYY-MM-DD"
          @change="changeDate"
        ></date-picker>
      </div>
      
      <div v-if="total >= data_array.length" class="results-count mt-4">
        Showing {{ data_array.length }} of {{ total }} Results
      </div>

      <div
        v-if="data_array.length > 0"
        class="earning-calendar overflow-x-scroll"
        :class = "[ title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : '']"
      >
        <div>SideBar docked = {{ !reduceButton }}</div>

        <ticker-table
          v-if="data_array.length > 0"
          :stocks_clickable="stocks_clickable"
          :data_array="data_array"
          :data_headers="data_headers"
          :sort_col_index="sort_col_index"
        ></ticker-table>
      </div>

      <h5 v-else-if="!loading" class="py-8 text-primary text-center">
        <vs-icon
          class="text-xl pr-2"
          icon="icon-info"
          icon-pack="feather"
        ></vs-icon>
        <span>{{ no_results_msg }}</span>
      </h5>
      
    </div>
    
    <div v-if="load_more_button" class="text-center">
      <vs-button class="mt-6" @click="showMore">{{ show_more_text }}</vs-button>
    </div>
    
    <div
      v-else-if="data_array.length > 0 && data_array.length > 20"
      class="text-center"
    >
      <vs-button class="mt-6" @click="showLess">Show Less</vs-button>
    </div>
  
  </div>
</template>

<script>
import DatePicker from "vue2-datepicker";
import "vue2-datepicker/index.css";
import TickerTable from "@/components/shared/tables/ThTickerTable.vue";

export default {
  name: "IPOEarnings",
  components: {
    DatePicker,
    TickerTable
  },
  data() {
    return {
      sort_index: this.sort_col_index,
      date: null,
      loading: false
    };
  },
  props: {
    title: {
      type: String,
      required: true
    },
    no_results_msg: {
      type: String,
      required: true
    },
    default_date: {
      type: String
    },
    data_array: {
      type: Array,
      required: true
    },
    data_headers: {
      type: Array,
      required: true
    },
    sort_col_index: {
      type: Number,
      required: true
    },
    stocks_clickable: {
      type: Boolean,
      default: false
    },
    load_more_button: {
      type: Boolean,
      default: false
    },
    show_more_text: {
      type: String,
      default: ""
    },
    total: {
      type: Number,
      default: 0
    }
  },
  watch: {
    data_array(oldVal, newVal) {
      this.loading = false;
      this.$vs.loading.close("#calendars-results > .con-vs-loading");
    }
  },
  methods: {
    changeDate(currentValue) {
      this.loading = true;
      this.$vs.loading({ container: "#calendars-results", scale: 0.6 });
      this.date = currentValue;
      // harcoded max 200 limit to get results
      this.$emit("update", currentValue, 200);
    },
    showMore() {
      this.$emit("showMore");
    },
    showLess() {
      this.$emit("showLess");
    }
  },
  created() {
    this.loading = true;
    this.date = this.default_date;
  },

  computed: {
    reduceButton: {
      get() {
        return this.$store.state.reduceButton;
      },
      set(val) {
        this.$store.commit("TOGGLE_REDUCE_BUTTON", val);
      }
    }
  }
};
</script>

<style lang="scss">
@media (min-width: 1015px) {
  .earning-calendar {
    overflow: hidden !important;
  }
}
</style>

Issues

(Emitted value instead of an instance of Error)

  Errors compiling template:

  v-else-if="!loading" used on element <h5> without corresponding v-if.

  37 |        ></ticker-table>
  38 |      </div>
  39 |      <h5 v-else-if="!loading" class="py-8 text-primary text-center">
     |          ^^^^^^^^^^^^^^^^^^^^
  40 |        <vs-icon
  41 |          class="text-xl pr-2"

  Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

  46 |      </h5>
  47 |    </div>
  48 |    <div v-if="load_more_button" class="text-center">
     |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  49 |      <vs-button class="mt-6" @click="showMore">{{ show_more_text }}</vs-button>
     |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  50 |    </div>
     |  ^^^^^^^^
  51 |    <div
     |  ^^^^^^
  52 |      v-else-if="data_array.length > 0 && data_array.length > 20"
     |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  53 |      class="text-center"
     |  ^^^^^^^^^^^^^^^^^^^^^^^
  54 |    >
     |  ^^^
  55 |      <vs-button class="mt-6" @click="showLess">Show Less</vs-button>
     |  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  56 |    </div>
     |  ^^^^^^^^
  57 |  </div>
     |  ^^^^^^

In case I remove the line containing the ternary operation

  :class = "[ title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : '']"
, everything functions smoothly. Why does combining the ternary operator in :class and v-if result in errors? Is there a way to utilize both simultaneously? Even after substituting v-if with v-else, the errors persist. However, omitting the ternary line eliminates the errors. What precisely triggers these errors?

Answer №1

Replace with the following

:class="{ 'earning-calendar' : title === 'Earnings Calendar' && reduceButton === false }"

Answer №2

The issue arises from the failure of quote matching due to nested double-quotes within a double-quoted attribute value in the class binding:

       👇 outer
:class="[
  title === "Earnings Calendar" && reduceButton === false ? "earning-calendar" : ''
]"          👆 inner          👆 inner                       👆 inner         👆 inner
 👆 outer

To resolve this, a quick solution is to replace the inner quotes with single-quotes:

:class="[
  title === 'Earnings Calendar' && reduceButton === false ? 'earning-calendar' : ''
]"

Furthermore, it's important to note that you are including the earning-calendar class twice (once statically and once dynamically through class binding):

class="earning-calendar overflow-x-scroll"
       ^^^^^^^^^^^^^^^^
:class="[
  title === 'Earnings Calendar' && reduceButton === false ? 'earning-calendar' : ''
]"                                                           ^^^^^^^^^^^^^^^^

You may want to consider removing the static class name or adjusting the dynamic one.

demo

An alternative, more concise and readable approach is to utilize the object syntax for class bindings, as demonstrated in another response here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing dotenv: Incorporating the value of one environment variable into the name and value of another environment variable

When it comes to my testing framework, I rely on dotenv for handling environment variables across different test environments. Currenty, I'm looking for a way to incorporate the value of a specific environment variable into both the value and name of ...

Issue encountered while trying to load electron-tabs module and unable to generate tabs within electron framework

I've recently set up the electron-modules package in order to incorporate tabs within my Electron project. Below are snippets from the package.json, main.js, and index.html files. package.json { "name": "Backoffice", "version": "1.0.0", "descr ...

Attempting to submit a form to Mailchimp with Vue.js and Axios causes a CORS error to occur

In my Vue.js application, I have a feature that sends email data from a form to Mailchimp using the Axios library. I recently learned that in order to bypass CORS restrictions when posting to Mailchimp's URL, I need to use the post-json version and a ...

Passing methods from child to parent components in Vue2 looped componentsHere is a

Currently, I am iterating through the root component, which contains a child component within it. <root-select v-for="offer in offers" > <child-options v-for="item in options" > </child-options> </root-select> However, when ...

Building a web application using the Nuxt.js framework and Express generator

Seeking help to seamlessly integrate an express app generated with express generator into my nuxt.js application. Came across this https://github.com/nuxt-community/express-template, although it seems to only cover basic express applications. Any recomme ...

react tried to recycle markup error

Working on server-side rendering with React, encountering an error mentioned below. Here is the context: I have 2 React components, each stored in its own separate folder: - react-components - component-1-folder - component-1 - component-2-fo ...

Modify background image upon hovering using AngularJS

I cannot seem to make the background images of my divs change. Despite trying various options, none of them have been successful. Here's an example of my code: <div ng-controller="mainController" class="main"> <div ng-repeat="land in lan ...

How can we efficiently validate specific fields within arrays and objects in express-validator by utilizing the body() method?

I have organized my field names in an array as follows: const baseFields = [ 'employeeNumber', 'firstName', 'lastName', 'trEmail', 'position' ]; These are the only input fields I need to focus on for valid ...

Use RxJS chaining to transform an observable of `File` objects into an observable of strings encoded in base64

I have successfully written code that converts my File object to base64: let reader = new FileReader(); reader.readAsDataURL(myFile); reader.onload = () => { let resultStrOrArrayBuf = reader.result; if (!(resultStrOrArrayBuf ...

Tips for displaying and sorting two requests within one console

I am currently working on a project to display both folders and subfolders, but only the folders are visible at the moment. function getParserTypes (types, subject) { return types.map((type) => { return { id: type.entry.id, name: type. ...

Guide to successfully setting up a Json server and ReactJS to run simultaneously on the same port

Currently, I am facing an issue while attempting to run my React application with a JSON server as the backend API. The problem arises when trying to run them on different ports due to a CORS error. I am currently seeking advice and looking for a solutio ...

Troubleshooting the inability to set percentage values in Bootstrap styling

My goal is to create a bar with thin bars, but my use of Bootstrap limits my control over sizes. <template> <div class="container-fluid mx-auto"> <div class="row"> <div class="square rounded-pill&qu ...

PHP and JavaScript: Understanding Variables

I currently have a View containing an Associative Array filled with information on accidents. Users will have the ability to click on a Country. Once clicked, I want to display accident-related data for that specific country. This data is pulled from PHP ...

What is the best way to incorporate a CSS transition without any dynamic property changes?

Is there a way to add a transition effect to a header when its size changes without a specified height value in the CSS? The header consists of only text with top and bottom padding, so as the text changes, the height adjusts accordingly. How can I impleme ...

Synchronously retrieving JSON data from a URL using JavaScript

I'm currently working on extracting the title of a YouTube video using jQuery to parse JSON. The issue I am facing is that it works asynchronously, resulting in the answer being displayed after the page has already loaded. Here's the current resu ...

Can you explain the significance of the regular expression pattern /(?:^|:|,)(?:s*[)+/g in Javascript?

When it comes to Jquery, the regexp pattern is defined as follows: var rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g; This particular pattern is designed to match strings such as "abc,[" and "abc:[", while excluding instances like "abc^[". But what doe ...

Using an anonymous function in Javascript to change the background color of a div on mouse-over directly from the HTML code

I came across this code snippet in the provided link and as a beginner in JavaScript, I am unsure how to call the JavaScript function from the HTML code. Due to them being anonymous functions, I am struggling to invoke them. Can someone guide me on how to ...

Unable to open modal using a button in PHP

<?php $result = mysqli_query($con, $sql); while ($row = mysqli_fetch_array($result)) { echo '<tr><td>'; echo '<h5 style="margin-left:6px; color:black;">' . $row['id'] . '</h5> ...

Creating multipart/form-data with varying Content-Types for each part using JavaScript (or Angular)

Apologies for the confusion, please refer to my update below I have a requirement to link my AngularJS Project with an existing RESTful API. This API uses POST requests that involve uploading a file and submitting form data in a request. However, one of t ...

Tips on retrieving complete information from mongoose when the schema contains a reference

I have a schema that includes [content, name, email], and I need to retrieve all three data fields and render them on the frontend simultaneously. Can you provide an example of JavaScript code that accomplishes this? const UserSchema = new mongoose.Schem ...