javascriptvue.jsvue-filter

Vuejs how to compare dates with filter in list


I'm learning vujs and got stuck on my own example with filter and date comparison. I got two similar strings (as dates '2020-02-02') in second row, and I should see the word 'today', but it doesn't work.

  1. why on typeof in template my dates with filter are numbers?

  2. what I'm doing wrong with comparison those dates? it's always false.

code you can see down here or https://jsfiddle.net/2awtdny4/9/

html:

<div id="app">

<div v-for="item in info">
  <div>
    <!-- I compare 2 dates as strings, and if it's true, I want to show word 'Today'  -->
    <span v-if="(item.date | yymmdd  === todayIs | yymmdd)" class="today">today</span>  
    <!-- else I want to show date as yyyy-mm-dd -->
    <span v-else>{{item.date | yymmdd}}</span>

    <!-- for some reason with filter date is NUMBER. why? in method and filter they should be stings -->
    <span>{{ typeof (item.date | yymmdd)}}</span>
    <span>{{ typeof (todayIs)}}</span>
  </div>
</div>

</div>

vue:

new Vue({
  el: "#app",
  data: {
    info: [
      { date: "2020-02-01 10:00", text: "first text" },  // date format from backend
      { date: "2020-02-02 15:00", text: "second text" },
      { date: "2020-02-03 15:00", text: "third text" },
      { date: "2020-02-04 18:00", text: "fourth text" },
    ],
    todayIs: null
  },
  methods: {
     today() {
        var today = new Date(),
          todayDate = ('0'+today.getDate()).slice(-2),
          todayMonth = ('0'+ (today.getMonth() + 1) ).slice(-2),
          todayYear = today.getFullYear();

        var day = '';
        day = todayYear + '-' + todayMonth + '-' + todayDate;

        this.todayIs = day;
    }
  },
  filters: {
    // cut yyyy-mm-dd format and return date as string
    'yymmdd': function (date) { 
      var newDay = new Date(date),
          currentDate = ('0'+newDay.getDate()).slice(-2),
          currentMonth = ('0'+ (newDay.getMonth() + 1) ).slice(-2),
          currentYear = newDay.getFullYear();

      var day = '';
      day = currentYear + '-' + currentMonth + '-' + currentDate;

      return day;
    }
  },
  created: function () {
      this.today()
  },
})

Solution

  • You can use filters only in mustache interpolations and v-bind expressions (the latter supported in 2.1.0+). Therefore it cannot be used like you have used it in the v-if.

    You can create a function in your methods for comparing dates like the following :

    compareWithToday(date){
        return this.$options.filters.yymmdd(date) === this.todayIs;
    }
    

    And then use this function to evaluate your v-if flag in template

    <span v-if="(item.date | yymmdd  === todayIs | yymmdd)" class="today">today</span>  
    

    Above should be replaced with the following :

    <span v-if="compareWithToday(item.date)" class="today">today</span>
    

    Here is the working jsfiddle of above : https://jsfiddle.net/17mp6ofe/

    Reference for filters : https://v2.vuejs.org/v2/guide/filters.html