rcarcia02
rcarcia02

Reputation: 977

Angular - trouble with fetching from array

so in my angular project, I've been instructed to make selectedEmployee: EmpInfo type and set the [value] of the select to emp and then use selectedEmployee as the object that I reference to display the data. I'm really new to Angular and not quite sure how to implement that. I thought that I did it right but in the browser, I'm getting an error that says "cannot read property 'EmpKey' of undefined in tracker.component.ts. I'm really stuck, any help is greatly appreciated. Thanks!

Here's my tracker.component.ts

import { Component, OnInit, Input} from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { PTODataService } from './pto-data.service';
import { PTOData } from './pto-data';
import { EmpInfoService } from './emp-info.service';
import { EmpInfo } from './emp-info'; 

@Component({
    selector: 'pto-tracker',
    templateUrl: `./tracker.component.html`,
    styleUrls: ['./tracker.component.css']
})

export class TrackerComponent implements OnInit{
    empInfo: EmpInfo[] = new Array<EmpInfo>();
    ptoData: PTOData[];
    isHidden: boolean = false;
    
    selectedEmployee: EmpInfo;

    public selectedType: string = "PTO";

    constructor(
        private empInfoService: EmpInfoService,
        private ptoDataService: PTODataService) { }

    getEmpInfo(): void {
        this.empInfoService.getEmpInfos().then(
            empInfo => this.empInfo = empInfo
            );
    }

    getPTOData(): void {
        this.ptoDataService.getPTODatas().then(
            ptoData => this.ptoData = ptoData
        );
    }

    ngOnInit(): void {
        this.getEmpInfo();
        this.getPTOData();
    }

    toggleSummary(): void {
        this.isHidden = !this.isHidden;
    }
}

my tracker.component.html

<div class="row">
  <div [ngClass]="{'col-xs-12':isHidden === true, 'col-xs-7': isHidden !== false}">
    <button class="btn btn-default btn-primary" style="width:50px; height: 50px; float:right; padding-bottom: 10px; padding-top: 10px;margin:5px;" (click)="toggleSummary()"><i class="fa fa-pencil-square-o fa-2x" aria-hidden="true"></i></button>
    
    <div class="col-xs-12 no-pad" style="padding-bottom:50px;">
      <div class="col-xs-3">
        <select class="form-control" id="empName" [(ngModel)]="selectedEmployee">
          <option selected="selected" disabled>Employee Name...</option>
          <option *ngFor="let emp of empInfo | orderByLast : 'LastName'" [ngValue]="emp">{{emp.EmpID}} - {{emp.FirstName}} {{emp.LastName}}</option>
        </select>
      </div>
      <div class="col-xs-2">
        <select class="form-control" id="PTOtype" [(ngModel)]="selectedType">
          <option selected="selected" value="PTO">PTO</option>
          <option value="etoEarned">ETO - Earned</option>
          <option value="etoUsed">ETO - Used</option>
          <option value="STDLTD">STD/LTD</option>
          <option value="Uncharged">Uncharged</option>
        </select>
      </div>
    </div>
    <div class="col-xs-12">
      <table class="table table-striped table-bordered">
        <thead>
          <tr>
            <th>Date</th>
            <th>Full/Half</th>
            <th>Hours</th>
            <th>Scheduled?</th>
            <th>Notes</th>
            <th>In P/R?</th>
          </tr>
        </thead>
        <tfoot>
          <tr>
            <td colspan="6">
              <span class="requestText">Requests:</span>
            </td>
          </tr>
        </tfoot>
        <tbody>
          <tr *ngFor="let pto of ptoData">
            <ng-container *ngIf="pto.type === selectedType">
              <ng-container *ngIf="pto.EmpKey === selectedEmployee?.EmpKey">
                <td>{{pto.date | date: 'MM/dd/y'}}</td>
                <td>{{pto.fullhalf}}</td>
                <td>{{pto.hours}}</td>
                <td>{{pto.scheduled}}</td>
                <td>{{pto.notes}}</td>
                <td>{{pto.inPR}}</td>
              </ng-container>
            </ng-container>
          </tr>
        </tbody>
      </table>
    </div>
    </div>
  <div *ngIf="isHidden" class="col-xs-5">
        <pto-summary [empInfo]="selectedEmployee"></pto-summary>
  </div>
</div>

my summary.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { EmpInfoService } from './emp-info.service';
import { TrackerComponent } from './tracker.component';
import { EmpInfo } from './emp-info'; 

@Component({
    selector: 'pto-summary',
    templateUrl: `./summary.component.html`,
    styleUrls: ['./summary.component.css']
})

export class SummaryComponent implements OnInit{

    empInfo: EmpInfo[];
    @Input() selectedEmployee: EmpInfo;

    timeVar = " hours";
    checkboxValue = false;

    constructor(private empInfoService: EmpInfoService) { }

    getEmpInfo(): void {
        this.empInfoService.getEmpInfos().then(
            empInfo => this.empInfo = empInfo
        );
    }

    ngOnInit(): void {
        this.getEmpInfo();
    }

    changeTime(): void {
        if (!this.checkboxValue)
        {
            this.timeVar = " hours"

            this.selectedEmployee.STDLTD = this.selectedEmployee.STDLTD * 8;
            this.selectedEmployee.Uncharged = this.selectedEmployee.Uncharged * 8;

            this.selectedEmployee.PTOBase = this.selectedEmployee.PTOBase * 8;
            this.selectedEmployee.PTOCarry = this.selectedEmployee.PTOCarry * 8;
            this.selectedEmployee.PTOBorrowed = this.selectedEmployee.PTOBorrowed * 8;
            this.selectedEmployee.PTOBalance = this.selectedEmployee.PTOBalance * 8;
            this.selectedEmployee.PTORequests = this.selectedEmployee.PTORequests * 8;
            this.selectedEmployee.PTORemaining = this.selectedEmployee.PTORemaining * 8;

            this.selectedEmployee.ETOEarned = this.selectedEmployee.ETOEarned * 8;
            this.selectedEmployee.ETORequests = this.selectedEmployee.ETORequests * 8;
            this.selectedEmployee.ETORemaining = this.selectedEmployee.ETORemaining * 8;
        }
        else
        {
            this.timeVar = " days"

            this.selectedEmployee.STDLTD = this.selectedEmployee.STDLTD / 8;
            this.selectedEmployee.Uncharged = this.selectedEmployee.Uncharged / 8;

            this.selectedEmployee.PTOBase = this.selectedEmployee.PTOBase / 8;
            this.selectedEmployee.PTOCarry = this.selectedEmployee.PTOCarry / 8;
            this.selectedEmployee.PTOBorrowed = this.selectedEmployee.PTOBorrowed / 8;
            this.selectedEmployee.PTOBalance = this.selectedEmployee.PTOBalance / 8;
            this.selectedEmployee.PTORequests = this.selectedEmployee.PTORequests / 8;
            this.selectedEmployee.PTORemaining = this.selectedEmployee.PTORemaining / 8;

            this.selectedEmployee.ETOEarned = this.selectedEmployee.ETOEarned / 8;
            this.selectedEmployee.ETORequests = this.selectedEmployee.ETORequests / 8;
            this.selectedEmployee.ETORemaining = this.selectedEmployee.ETORemaining / 8;
        }
    }
}

and my summary.component.html

<div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title pull-left">{{selectedEmployee.LastName | uppercase}} Summary</h3>
    <div style="float: right;">
      <div class="onoffswitch">
        <input [(ngModel)]="checkboxValue" (change)="changeTime()" type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch" checked>
        <label class="onoffswitch-label" for="myonoffswitch">
          <span class="onoffswitch-inner"></span>
          <span class="onoffswitch-switch"></span>
        </label>
      </div>
    </div>
    <div class="clearfix"></div>
  </div>
  <div class="panel-body">
    <form class="form-horizontal" role="form" style="overflow-x:auto;">
      <fieldset>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-5"> Status </label>
            <div class="col-xs-7">
              <select class="form-control" id="empStatus" [(ngModel)]="selectedEmployee.EmpStat" name="empStatus">
                <option value="Current">Current</option>
                <option value="Terminated">Terminated</option>
              </select>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-5"> Anniversary </label>
            <div class="col-xs-7">
              <div class="input-group">
                <input class='form-control' type="text" id="empAnniversary" [(ngModel)]="selectedEmployee.Anniversary" name="empAnniversary" />
                <span class="input-group-addon">years</span>
              </div>
            </div>
          </div>
         </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-5"> Start Date </label>
            <div class="col-xs-7">
              <input class='form-control' type="text" id="empStartDate" [ngModel]="selectedEmployee.StartDate | date: 'MM/dd/y'" name="empStartDate"/>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-5"> Adjusted Start </label>
            <div class="col-xs-7">
              <input class='form-control' type="text" id="empAdjustedStart" [ngModel]="selectedEmployee.AdjustedStart | date: 'MM/dd/y'" name="empAdjustedStart"/>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-5"> STD/LTD </label>
            <div class="col-xs-7">
              <div class="input-group">
                <input class='form-control' type="text" id="empSTDLTD" [(ngModel)]="selectedEmployee.STDLTD" name="empSTDLTD" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-5"> Uncharged </label>
            <div class="col-xs-7">
              <div class="input-group">
                <input class='form-control' type="text" id="empUncharged" [(ngModel)]="selectedEmployee.Uncharged" name="empUncharged" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
        </div>
      </fieldset>


      <fieldset>

        <h4>PTO</h4>
        <br />

        <div class="col-xs-12">
          <div class="form-group">
            <div class="col-xs-1"></div>
            <label class="col-xs-2"> Base </label>
            <div class="col-xs-3">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoBase" [(ngModel)]="selectedEmployee.PTOBase" name="ptoBase" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
            <div class="col-xs-6">
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-2" style="font-weight: bold;"> &#43; </label>
            <label class="col-xs-4"> Carryover </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoCarry" [(ngModel)]="selectedEmployee.PTOCarry" name="ptoCarry" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <div class="col-xs-1"></div>
            <label class="col-xs-4"> Balance </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoBalance" [(ngModel)]="selectedEmployee.PTOBalance" name="ptoBalance" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
            <div class="col-xs-1"></div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-2" style="font-weight: bold;"> &#8213; </label>
            <label class="col-xs-4"> Borrowed </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoBorrowed" [(ngModel)]="selectedEmployee.PTOBorrowed" name="ptoBorrowed" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
          <hr style="border: solid 1px black;border-bottom:1px solid black;clear:both" />
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-1" style="font-weight: bold;"> &#8213; </label>
            <label class="col-xs-4"> Requests </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoRequests" [(ngModel)]="selectedEmployee.PTORequests" name="ptoRequests" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
            <div class="col-xs-1"></div>
          </div>
          <hr style="border: solid 1px black;border-bottom:1px solid black;clear:both" />
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-2" style="font-weight: bold;"> &#61; </label>
            <label class="col-xs-4"> Balance </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoBalance" [(ngModel)]="selectedEmployee.PTOBalance" name="ptoBalance" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group">
            <label class="col-xs-1" style="font-weight: bold;"> &#61; </label>
            <label class="col-xs-4"> Available </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoRemaining" [(ngModel)]="selectedEmployee.PTORemaining" name="ptoRemaining" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
            <div class="col-xs-1"></div>
          </div>
        </div>
      </fieldset>


      <fieldset>

        <h4>ETO</h4>
        <br />

          <div class="col-xs-6">
            <div class="form-group">
              <div class="col-xs-2"></div>
              <label class="col-xs-4"> Earned </label>
              <div class="col-xs-6">
                <div class="input-group">
                  <input class='form-control' type="text" id="etoEarned" [(ngModel)]="selectedEmployee.ETOEarned" name="etoEarned" />
                  <span class="input-group-addon">{{timeVar}}</span>
                </div>
              </div>
            </div>
            <div class="form-group">
              <label class="col-xs-2"> &#8213; </label>
              <label class="col-xs-4"> Requests </label>
              <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="etoRequests" [(ngModel)]="selectedEmployee.ETORequests" name="etoRequests" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
              </div>
            </div>
            <hr style="border: solid 1px black;border-bottom:1px solid black;clear:both" />
            <div class="form-group">
              <label class="col-xs-2"> &#61; </label>
              <label class="col-xs-4"> Available </label>
              <div class="col-xs-6">
                <div class="input-group">
                  <input class='form-control' type="text" id="etoRemaining" [(ngModel)]="selectedEmployee.ETORemaining" name="etoRemaining" />
                  <span class="input-group-addon">{{timeVar}}</span>
                </div>
              </div>
            </div>
          </div>
          <div class="col-xs-6"></div>

      </fieldset>
    </form>
  </div>
</div>

Upvotes: 0

Views: 45

Answers (1)

Teddy Sterne
Teddy Sterne

Reputation: 14221

At line 7 of tracker.component.html you need to use two-way data binding to keep the value in sync with the model like so:

[(ngModel)]="selectedEmployee"

Because the value is not set initially you need to use the elvis operator to access properties on the object. This will short-circuit if any part on the object chain is undefined. Like so:

<ng-container *ngIf="pto.EmpKey === selectedEmployee?.EmpKey">

To pass the selected employee to the summary component you need to setup an input parameter like so:

export class SummaryComponent implements OnInit{

    @Input() selectedEmployee: EmpInfo;
}

And then provide that to the component in the tracker-component.html like so:

<pto-summary [selectedEmployee]="selectedEmployee"></pto-summary>

Upvotes: 2

Related Questions