0

I am trying to count the number of times each value occurs for 'classtext' which is in data.items

However, by adding a function below to do that for each new inputted classtext on button click, I get 0 returned, even if I previously input several 'test' in the classtext field. I am very new in vuejs so obviously I am doing something wrong.

The code looks like this:

<!DOCTYPE html>
<html>
<script src="https://vuejs.org/js/vue.js"></script>
<style>
/* Vue List Item transition */
.list-item-enter-active,
.list-item-leave-active {
  transition: opacity 0.3s, -webkit-transform 0.3s;
  transition: opacity 0.3s, transform 0.3s;
  transition: opacity 0.3s, transform 0.3s, -webkit-transform 0.3s;
  -webkit-transform-origin: left center;
          transform-origin: left center;
}
.list-item-enter,
.list-item-leave-to {
  opacity: 0;
  -webkit-transform: scale(0.5);
          transform: scale(0.5);
}
/* //////////////////////////////////////// */
/* Basic Styles */
html {
  background: #eee;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.list {
  background: #FFF;
  margin: auto;
  padding: 1em 1em 1em;
  box-shadow: 0 5px 30px rgba(0, 0, 0, 0.2);
}
.list :last-child {
  margin-bottom: 0;
}
.list__ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}
.list__input {
  display: flex;
  margin-bottom: 0.5em;
}
.list__item {
  display: block;
  margin-bottom: 0.25em;
}

</style>
</head>

<body>
  <div id="example-1" class="list">

  <div class="list__input" @keydown.enter="add">
    <button v-on:click="count">+</button>
    <input v-model="newBeneficiary" placeholder="Add beneficiary"  />
    <input v-model="newClass" placeholder="Add new task topic" />
    <input v-model="newItem" placeholder="Add new task text"  />
  </div>

  <transition-group name="list-item" tag="ul" class="list__ul">
    <li class="list__item" v-for="item in items" :key="item">
      Timestamp: {{ item.timestamp }} <br />
      Beneficiary: {{ item.beneficiarytext }} <br />
      Topic: {{ item.classtext }} <br />
      Task: {{ item.message }}
    </li>
  </transition-group>

</div>
</body>
<script>
/**
 * Return a timestamp with the format "m/d/yy h:MM:ss TT"
 * @type {Date}
 */

function timeStamp() {
  var now = new Date();
  var date = [ now.getMonth() + 1, now.getDate(), now.getFullYear() ];
  var time = [ now.getHours(), now.getMinutes(), now.getSeconds() ];
  var suffix = ( time[0] < 12 ) ? "AM" : "PM";
  time[0] = ( time[0] < 12 ) ? time[0] : time[0] - 12;
  time[0] = time[0] || 12;
  for ( var i = 1; i < 3; i++ ) {
    if ( time[i] < 10 ) {
      time[i] = "0" + time[i];
    }
  }
  return date.join("/") + " " + time.join(":") + " " + suffix;
}

var app = new Vue({
  el: '#example-1',
  data: {
    items: [
      /*{ timestamp:'testdate', beneficiarytext: 'TestBeneficiary', classtext: 'TestTopic', message: 'TestMessage' }*/
    ]
  },
  methods: {
    /* MIGHT BE USED LATER TO DELETE TASKS
    remove: function(item){
      this.items.splice( this.items.indexOf(item), 1 );
    },
    */
    add: function(){
      this.items.unshift({ timestamp: timeStamp(), beneficiarytext: this.newBeneficiary, classtext: this.newClass, message: this.newItem });
      this.newItem = '';
      console.log(this.items);
    },
    count: function() {
      var counting = this.items.reduce(function (n, class1) {
      return n + (class1.classtext == this.newClass);
    }, 0)}
  }
})
</script>
</body>

</html>
Kristian Vybiral
  • 469
  • 6
  • 18

1 Answers1

1

You didn't bind this to the reducer function. Use

this.items.reduce((n, class1) => { ... })

or

this.items.reduce(function (n, class1) { ... }.bind(this))

See How does the “this” keyword work?.


The compute the counts for each classtext in the array:

this.items.reduce((map, item) => {
  map.set(item.classtext, (map.get(item.classtext) || 0) + 1)
  return map
}, new Map())

// Returns Map of (classtext, count) pairs:
// {
//   apple => 2,
//   banana => 6,
// }
Decade Moon
  • 27,192
  • 7
  • 63
  • 85
  • Thanks! Just a quick additional question: how would I go about checking the count for each unique classtext already located in the data.items, not just what is inputted? – Kristian Vybiral Sep 12 '18 at 12:15
  • Are you asking how to compute the counts for each unique classtext, not just `newClass`? – Decade Moon Sep 12 '18 at 12:29
  • Sorry I was vague. I meant to say for all unique values provided in the classtext: 'value' pair. So if I have often recurring values in the classtext inputted by user and appended to the data items, it would possible to find the count of all unique values that the user inputted. – Kristian Vybiral Sep 12 '18 at 12:36
  • See my edit (I *think* that's what you mean), but it would be better to ask it as a new question in the future. – Decade Moon Sep 12 '18 at 12:42
  • Thanks, this was useful. It is still a challenge to figure out how to display the counts in the dom though – Kristian Vybiral Sep 12 '18 at 20:50