0

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()
  },
})

2 Answers 2

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

ohh, I thought v-if-statement is more flexible and it supports filters. thanks for the explanation ) so simple
@v-orlov Well the template syntax in vue is not that flexible. There are a lot of things that you can't do in it. Have a look at this : vuejs.org/v2/guide/syntax.html#Using-JavaScript-Expressions
1

You can not use filters like this. If you take a look at the browser console for your linked example, its is full of warnigns:

vue.js:634 [Vue warn]: Property or method "yymmdd" is not defined on the instance but referenced during render.

It is because filters are usable in two places: mustache interpolations and v-bind expressions (the latter supported in 2.1.0+). Filters should be appended to the end of the JavaScript expression, denoted by the “pipe” symbol

Convert your filter to regular method and use computed property to convert your data one time instead of handling conversion in template (on every render)

methods: {
  convertDate(d) {
    // conversion
  }
},
computed: {
  convertedData() {
      return this.info.map(i => ({ ...i, date: this.convertDate(i.date)}))
  }
}

Sample

1 Comment

thank you! good approach to solving the problem with convert data on render. really useful for me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.