1

i can`t figure out how can i gropBy my data from Json when i have this kind of values

    2017-10-16 12:07:07
2017-10-16 12:07:07
2017-10-16 15:09:08
2017-10-16 15:09:08
2017-10-16 15:09:08
2017-10-16 15:09:08
2017-10-16 15:09:08
2017-10-16 18:11:09
2017-10-16 18:11:09
2017-11-29 17:26:57
2017-11-29 17:26:57
2017-11-29 17:26:57
2017-11-29 19:31:03

My template

 <div class="container">
      <div class="row">
          <div class="col-5">
               {% for date , block in block | groupby("date") %}
                 <div class="date">{{date |date }}</div>
              {% endfor %}

          </div>
      </div>
  </div>

and in output i have

16 Oct
16 Oct
16 Oct
3 Nov
29 Nov
29 Nov

i want to have

  16 Oct
  3 Nov
  29 Nov

Maybe in due to at first i took all data from Json , then i grouped it and only after that i use my dateFilter , but how can i due it in different way?

My gulpfile.js gulpfile

update 19.12.18

<div class="container">
       <div class="row">
            {% for date, block in block | groupby("date", "datefilter") %}
           <div class="col-5">
                <div class="date">
                        <h3> {{date}}</h3>
                        <p>amount {{block.length}}</p> // this line will give me amount of products for every day . 
                    </div>
              {% for id, block in block | groupby("id") %}
               <div class="id"> 
              {% for name, block in block | groupby("name") %}
                <p>{{name}} № {{ id }}  </p>
             </div>
               {% endfor %}
            {% endfor %}
           </div>

            {% endfor %}
       </div>
   </div>

example output

Gosha Travin
  • 25
  • 1
  • 7

3 Answers3

2

Below I improved standard groupby(prop) filter to groupby(prop, filter).

In my code I use roundDate instead date name for date-rounder-filter.

var nunjucks  = require('nunjucks');
var env = nunjucks.configure();

env.addFilter('roundDate', (e) => e.substring(0, 7));

env.addFilter('groupby', function (arr, prop, filter) {
    var res = {};
    var iterator = typeof prop == 'function' ? prop : (e) => e[prop];
    var func = this.env.filters[filter] || ((e) => e);
    arr.forEach(function (e, i) {
        var key = func(iterator(e, i));
        (res[key] || (res[key] = [])).push(e);
    })
    return res;
})

var data = [
    {date: "2017-10-16 12:07:07", value: "123"},
    {date: "2017-10-16 12:07:07", value: "123"},
    {date: "2017-10-16 15:09:08", value: "123"},
    {date: "2017-10-16 15:09:08", value: "123"},
    {date: "2017-10-16 15:09:08", value: "123"},
    {date: "2017-10-16 15:09:08", value: "123"},
    {date: "2017-10-16 15:09:08", value: "123"},
    {date: "2017-10-16 18:11:09", value: "123"},
    {date: "2017-10-16 18:11:09", value: "123"},
    {date: "2017-11-29 17:26:57", value: "123"},
    {date: "2017-11-29 17:26:57", value: "123"},
    {date: "2017-11-29 17:26:57", value: "123"},
    {date: "2017-11-29 19:31:03", value: "123"}
]

var res = env.renderString(`
    {% for a, items in data | groupby('date', 'roundDate') %}
       {{a}} {{items.length}}
    {% endfor %}
    `,
    {data}
);

console.log(res);
Aikon Mogwai
  • 4,954
  • 2
  • 18
  • 31
0

Your group by is returning 16 Oct multiple times because you have different time values listed on that date. If you first format your dates to only show the date and not the time, your group by should work. You could try this to extract only the dart part - you can substitute the locale string for another of your preference if you wish.

var date = new Date("2017-11-29 19:31:03").toLocaleDateString("en-US");
console.log(date);
sauntimo
  • 1,531
  • 1
  • 17
  • 28
  • Is it possible acording to this structure {% for date, block in block | groupby("date") %} to do it inside , or i can only try to store date from Json file somewhere , then filter it and only after that groubBy ? – Gosha Travin Dec 16 '18 at 11:43
0

i did like this , is it right ?

var manageEnvironment = function(environment) {

        environment.addFilter('datefilterq', dateFilter);
        dateFilter.setDefaultFormat('D MMM');
        environment.addFilter('groupby', function (arr, prop, filter) {
          var res = {};
          var iterator = typeof prop == 'function' ? prop : (e) => e[prop];
          var func = this.environment.filters[filter] || ((e) => e);
          arr.forEach(function (e, i) {
              var key = func(iterator(e, i));
              (res[key] || (res[key] = [])).push(e);
          })
          return res;
        })


}
Gosha Travin
  • 25
  • 1
  • 7
  • Try to change `this.environment` to `environment`. It looks like that you have another scope for `this`. – Aikon Mogwai Dec 16 '18 at 19:45
  • ohh it`s work , but still can`t understand how it is work , you just change the command filter or what ? if you have some time can you describe this code ? – Gosha Travin Dec 17 '18 at 11:55
  • It's a dark magic, ha-ha! Seriously, I used a [api::addFilter](http://mozilla.github.io/nunjucks/api.html#addfilter) to redefine `groupby` (it's possible to create another filter e.g. `groupby2` but my filter has same purpose, so overide is more suitable). The filter code is some modification of original `groupby` (I extracted it from [nunjucks source](https://github.com/mozilla/nunjucks/blob/master/nunjucks/src/lib.js#L170)). – Aikon Mogwai Dec 17 '18 at 13:21
  • now it`s clear , thank you ) but also i have one more queston to you it`s about nunjucks , acording to this {% for blocks in block %} {{blocks.quantity * blocks.price}} {% endfor %} i will get separeted numbers from every block , it is possible to sum it ? i tryed to use ( | sum) but is doesnot work , and is it possible to count how many document uner the 16 `th how to get quantity of document wich i got from json file ? – Gosha Travin Dec 17 '18 at 15:01
  • `sum` works with number array e.g. `[10, 20, 5]`. In your case you have `[{price: 10, quantity: 1}, {price: 25, quantity: 10}, ...]`. To solve this trouble you can add another filter: `env.addFilter('mysum', (arr) => arr.map(e => e.quantity * e.price).reduce((sum, e) => sum + e, 0));`. – Aikon Mogwai Dec 17 '18 at 15:58
  • To get count use `length` property e.g. `data.length`. – Aikon Mogwai Dec 17 '18 at 15:59
  • Thank you for your time very much !!!! but again (( filter mysum does`t work , arr.map is not a function {{blocks.quantity * blocks.price | mysum }} , and about data.length how should i use it ? when i try to count this method count numbers or letters – Gosha Travin Dec 18 '18 at 15:50
  • Use `{{blocks | mysum }}` :) – Aikon Mogwai Dec 18 '18 at 16:29
  • still arr.map is not a function – Gosha Travin Dec 18 '18 at 16:56
  • I post complete example [here](https://stackoverflow.com/a/53842181/6121703). I think that `blocks` isn't an `Array`. – Aikon Mogwai Dec 18 '18 at 22:42
  • Yep that`s right , i did it ) but i think i have some problems in my template in due to , if i will use block.length it will gime me the number of products wich i have for each day , for instace for 16`th i have 10 products , but for every day i have some amount of documents and inside of every doc i have products , is it possible to count number of doc , not products ? i will upload template in my post , and output also. – Gosha Travin Dec 19 '18 at 09:52
  • I think that you should find out how to write own filters. Don't copy code, write it yourself! There is a good start point to learn `arrow function` and some array methods e.g. `map` and `reduce`. I recommend [this site](https://learn.javascript.ru/) to learn `js`. – Aikon Mogwai Dec 19 '18 at 11:49
  • ofc i will , but to solve this problem i need to write new filter ? And this filter should return value from number of docs right ? – Gosha Travin Dec 19 '18 at 11:57
  • Ask your team leader :) You can solve this task by many ways: add custom filter, add global function, prepare data before pass it to nunjucks, etc. – Aikon Mogwai Dec 19 '18 at 12:14
  • Thanks :) i dont have team leader , at this moment i struggle with creating new filter ) – Gosha Travin Dec 19 '18 at 15:44
  • after 4 hours still can't figure out , every time i get objects, not number of this objects; – Gosha Travin Dec 19 '18 at 20:29
  • Contact me to lb.im@ya.ru if you still have a trouble. I'll give you a small online lesson about `nunjucks`-filters. – Aikon Mogwai Dec 20 '18 at 18:52