wonder95 wonder95 - 5 months ago 8
AngularJS Question

Organizing objects hierarchically by two levels in angularjs

I'm working on an Angular app that utilizes a cell modifier inside a custom cell template in Angular Bootstrap Calendar. Inside each cell, instead of a standard event, I'm placing a set of tables that are used for signing up for shifts at a station for that day. The tables are split into two groups; am and pm, and within each am/pm group, there is a table for each station, with three rows in each table.

AM

| 1 |Position|Name |

| |Pos 1 |Name 1|

| |Pos 2 |Name 2|

| |Pos 3 |Name 3|

| 2 |Position|Name |

| |Pos 1 |Name 1|

| |Pos 2 |Name 2|

| |Pos 3 |Name 3|

PM

| 1 |Position|Name |

| |Pos 1 |Name 1|

| |Pos 2 |Name 2|

| |Pos 3 |Name 3|

| 2 |Position|Name |

| |Pos 1 |Name 1|

| |Pos 2 |Name 2|

| |Pos 3 |Name 3|

Inside of my cell modifier function, I get an array of shift objects for that day, and each shift object contains the ampm value and the station value:

{
"_id": "57776537ac0a88010063b9b9",
"modified": "2016-07-02T06:54:47.518Z",
"data": {
"station": "1",
"date": "2016-07-01T07:00:00.000Z",
"ampm": "pm",
"slots": [
{
"position": "AO",
"name": ""
},
{
"position": "FF",
"name": {
"_id": "57776507ac0a88010063b9b8",
"modified": "2016-07-02T06:53:59.661Z",
"data": {
"group": "suppression",
"driving": {
"n": false,
"d": true,
"ao": false,
"wt": false
},
"emtLevel": "b",
"secondaryPhoneNumber": "",
"primaryPhoneNumber": "5556781234",
"emailAddress": "person.one@mysite.com",
"fullName": "Person One",
"userName": "person.one",
"assignedStation": "18",
"probationary": false
},
"form": "57427ba554ec330100dad645",
"created": "2016-07-02T06:53:59.644Z",
"externalIds": [],
"access": [],
"roles": [
"573511a8ffaa7a0100a5718a"
],
"owner": "57776507ac0a88010063b9b8"
}
},
{
"position": "FF",
"name": {
"_id": "57439d856e67b40100d4c420",
"modified": "2016-05-24T00:17:09.493Z",
"data": {
"userName": "person.two",
"fullName": "Person Two",
"emailAddress": "person.two@mysite.com",
"primaryPhoneNumber": "5555556666",
"secondaryPhoneNumber": "",
"assignedStation": "",
"emtLevel": "b",
"driving": {
"d": true
},
"group": "suppression"
},
"form": "57427ba554ec330100dad645",
"created": "2016-05-24T00:17:09.474Z",
"externalIds": [],
"access": [],
"roles": [
"573511a8ffaa7a0100a5718a"
],
"owner": "5734bba2ffaa7a0100a57029"
}
}
]
},


So the issue is how to take those objects and organize them into the two groupings mentioned above so that I can just loop through them with ngRepeat in my template. What I have so far is this:

vm.cellModifier = function(cell) {
cell.text = 'Test Text';
var shifts = vm.events;
// Get the date for the cell.
this.cellDate = moment(cell.date).format('YYYY-MM-DD');
// Iterate over shifts to get ones for this day.
this.cell = cell;
this.todayShifts = {};
shifts.forEach(function(shift, index, allShifts) {
var shiftDate = moment(shift.data.date).format('YYYY-MM-DD');
// Now we need to see if this shift belongs to this day.
if (moment(vm.cellDate).isSame(moment(shiftDate))) {
// Shift is today, so let's put it into the appropriate array.
if (typeof vm.todayShifts[shift.data.ampm] == 'undefined') {
vm.todayShifts[shift.data.ampm] = shift;
} else {
vm.todayShifts[shift.data.ampm].push(shift);
}
}
});
// Add arrays to cell object.
cell.todayShifts = vm.todayShifts;
};


That gives
vm.todayShifts[am]
and
vm.todayShifts[pm]
, but I also would like to get the second level so that I have
vm.todayShifts[am][1]
,
vm.todayShifts[am][2]
etc. Is there an easier way to do what I'm trying to do (I'm fairly certain there is) than adding another section of statements? I'm wondering if a custom directive or component might be cleaner, because then I could just pass my data into that controller, but even then, I would still need to get my data arranged properly so it can be displayed in the proper order.

Hopefully this all makes sense.

Thanks.

Answer

I think you are actually pretty close... Try this which will always put the data in the format you are asking for.

shifts.forEach(function(shift, index, allShifts) {
  var shiftDate = moment(shift.data.date).format('YYYY-MM-DD');
  // Now we need to see if this shift belongs to this day.
  if (moment(vm.cellDate).isSame(moment(shiftDate))) {
    // Shift is today, so let's put it into the appropriate array.
    if (typeof vm.todayShifts[shift.data.ampm] == 'undefined') {

      // Initialize the shifts as an array.
      vm.todayShifts[shift.data.ampm] = [];
    }

    // Push the shift onto the array.
    vm.todayShifts[shift.data.ampm].push(shift);
  }
});