0

I have schema similar to this:

Schema.Adviser = new SimpleSchema({
  "firstName": {
  type: String
  }
});

Schema.Orders = new SimpleSchema({
    "adviserId": {
    type: Object
  },
  "period": {
    type: Date
  },
  "order": {
    type: Number,
    min: 0
  }
});

I need to render a table like this:

first name | January | February

Bob | 1 | 0

Bill | 0 | 1

Each value is an input field that is editable.

If for example there is no order record for Bob in January I need January to still render, ideally with a 0 such that someone can add a January order.

Something like this:

months is an array of months to be shown. Each follows the format: Mon Feb 01 2016 00:00:00 GMT+0000

{{#each month in months}}
  {{#each getOrders}}
    {{#if equals month period}}{{order}}{{/else}}0{{/if}}
  {{/each}}
{{/each}}

Not only can I not get this to work, but before spending much more time trying to debug the issue I'm wondering if this is really the best way to do this.

Any advice?

Many thanks

user1496093
  • 189
  • 3
  • 15

1 Answers1

1

var months = ['Jan', 'Feb', 'Mar'];
var advisors = [{
  ID: 1,
  name: 'Bob'
}];
var emptyMonthArray = [0, 0, 0];
orders = [{
  advisorID: 1,
  period: new Date(),
  order: 3
}];

function getAdvisors() {
  var returnArray = [];
  advisors.forEach(function(a) {
    var returnObject = {
      name: a.name,
      monthData: emptyMonthArray.slice(0)
    };
    orders.forEach(function(o, i) {
      if (o.advisorID === a.ID) {
        returnObject.monthData[o.period.getMonth()] = o.order;
      }
    });
    returnArray.push(returnObject);
  });
  return returnArray;
}
console.log(getAdvisors());

I think a bit cleaner way of doing this is to make a getAdvisors helper that would process and transform the data and return something like

[
{name:'Bill', monthData:[0,1,0,2,...]},
{name: 'Bob', monthData:[...]}
]

which much neater could be expressed in a Template something like this:

<tr>
    <th>Name</th>
    {{#each month in months}}
       <th> {{monthname}}</th>
    {{end each}}
</tr>
{{#each advisor in getAdvisors }}
<tr>
    <td>{{name}}</td>
    {{#each monthData in advisor}}
       {{td>{{this}}</td>
    {{end each}}
</tr>
{{end each}}

EDIT: added a fiddle https://jsfiddle.net/runjep/1xrp1gfq/ (this will only work the first 3 months of the year ;-) after that you would have to add 'Apr',...

EDIT again using your fiddle https://jsfiddle.net/runjep/0qy34pfe/3/ Unfortunately meteorpad is down so here's what I think will work.

{{#each advisers}}
  {{firstName}}
  {{#each monthData}}
    {{this}}
  {{/each}}
{{/each}}
Rune Jeppesen
  • 1,121
  • 13
  • 22
  • Hi Rune thank you for your reply. Lets say "Bob" has an order for February but not for January, how can I transform the data because only one record will exist in the order collection for February? I totally agree, if I could output to the template something like "Jan: 0, Feb: 1" that would be perfect, but because "Jan" doesn't exist I am stuck in loop hell trying to work this out. Thanks again! – user1496093 Feb 19 '16 at 11:05
  • Something like this: https://jsfiddle.net/runjep/1xrp1gfq/ Not very optimized. I don't know your data model but perhaps data should be joined in the publications? – Rune Jeppesen Feb 19 '16 at 11:28
  • Schemas: https://jsfiddle.net/mishy111/0qy34pfe/ I'm using publish-composite to achieve the join. Looking at my jsfiddle would you be looking to replace my "advisers" and "orderGetter" helpers with something like what you very kindly posted? Many thanks – user1496093 Feb 19 '16 at 11:42
  • Yes - perhaps only the orderGetter: https://jsfiddle.net/runjep/0qy34pfe/1/ (I updated and renamed it) – Rune Jeppesen Feb 19 '16 at 11:52
  • Hi Rune Just so I understand, I should now be using {{#each}} over monthData right? and then using {{order}} to show whether it's a zero, or actual data? Thanks again for your help – user1496093 Feb 19 '16 at 12:07
  • Hi Rune. Only issue stopping it from rendering is TypeError: o.period.getMonth is not a function. Period is of form ISODATE() from mongo. I tried using Date.parse to no avail. – user1496093 Feb 19 '16 at 12:52
  • I don't know that format - but getMonth can be used on normal Date objects. Have you tried google it http://stackoverflow.com/questions/11486779/formatting-isodate-from-mongodb (or use another function which returns the month from the date as a number) – Rune Jeppesen Feb 19 '16 at 12:55
  • I have sorted that thanks. Just one last question, if I wanted to also return "outstanding" (see https://jsfiddle.net/mishy111/0qy34pfe/ from account schema) how would I do that? Something like this? returnArray[nD.getMonth()] = [o.order, o.outstanding]; – user1496093 Feb 19 '16 at 13:06
  • https://jsfiddle.net/runjep/0qy34pfe/4/ this adds the outstanding in a paranthesis. If you want it in it's own property :https://jsfiddle.net/runjep/0axL8y5f/1/ but then it should be used like this in the template {{#each monthData}} {{order}},{{outstanding}} {{/each}} as the elements in the array are no longer simple objects – Rune Jeppesen Feb 19 '16 at 13:48
  • Rune, thank you so much for your help. This had been driving me crazy for 2 days. Really much appreciated. – user1496093 Feb 19 '16 at 13:58
  • Just out of interest, is there a way to isolate between say, June and July rather than print the entire year? Not a biggie, but helpful. – user1496093 Feb 19 '16 at 14:08
  • Set the fromMonth and toMonth somewhere in a Session object. The month helper should also use these values https://jsfiddle.net/runjep/0axL8y5f/2/ (so that the months shown matches the data in monthData) – Rune Jeppesen Feb 19 '16 at 14:34
  • Fantastic. Thank you! – user1496093 Feb 19 '16 at 15:40