Aggregate with meteor? (aggregate is not a function)

Now it works:

<span class="grey-light pt-3 mt-3">
   <select v-model="thisYear">
     <option v-for='(value, key) in getyears(thecat.name)' :value='key'>{{key}} - {{value}} gang(e)</option>
      
    </select>
</span>

It worked when i moved it to methods outside data

methods: {
      getyears(category) {
  return Events.find({category: category})
    .fetch()
    .map(doc => doc.thedate.substr(0, 4))
    .reduce((years, year) => {
    if (year in years) {
      years[year]++;
    } else {
      years[year] = 1;
    }
    return years;
  }, {});
},

Big thanks for your help robfallows

1 Like

One last thing, how to SORT so newest year comes first?

2019 3 time
2018 1 time

and not like now:

2018 1 time
2019 3 time

You could add a descending sort into the chain. As the (string) year can be represented as a number, this should work:

  getyears(category) {
    return Events.find({ category: category })
      .fetch()
      .map(doc => doc.thedate.substr(0, 4))
      .sort((a,b) => ~~b - ~~a )
      .reduce((years, year) => {
        if (year in years) {
          years[year]++;
        } else {
          years[year] = 1;
        }
        return years;
      }, {});
  },

I still get the oldest year first,

I can se that sort works here: https://www.w3schools.com/js/tryit.asp?filename=tryjs_array_sort3

Ah, yes. Unfortunately, Node ensures that object keys which appear to be numeric are stored/retrieved in ascending order, which I’d forgotten. The solution becomes a little more complex:

getyears(category) {
  const result = Events.find({ category })
    .fetch()
    .map(doc => doc.thedate.substr(0, 4))
    .reduce((years, year) => {
      if (year in years) {
        years[year]++;
      } else {
        years[year] = 1;
      }
      return years;
    }, {});
  return Object.keys(result).sort((a, b) => ~~b - ~~a)
    .map(year => ({ year, count: result[year] }));
}

:hand: The result is now an array of objects, such as:

[
  {
    "year": "2019",
    "count": 1
  },
  {
    "year": "2018",
    "count": 5
  },
  {
    "year": "2011",
    "count": 3
  }
]

Which means you will need to alter your presentation code accordingly.

Alternatively, you could use the original code, but ensure the year is prefixed with a space, which is sufficient to ensure that the order is preserved. The map would then look like:

.map(doc => ` ${doc.thedate.substr(0, 4)}`)

and you can continue to use your current presentation code.

1 Like

I’ve never thought to use reduce like this, that’s awesome