I'm learning Angular2+ and doing my assignment now. I spent approximately 3 hours trying to debug this bug. I have a problem with my ngFor statement especially with the [value] part. Something is wrong with my code.
The error is :
EmployeeComponent.html:27 ERROR TypeError: Cannot read property 'PositionName' of undefined at Object.eval [as updateDirectives] (EmployeeComponent.html:27) at Object.debugUpdateDirectives [as updateDirectives] (core.js:14689) at checkAndUpdateView (core.js:13836) at callViewAction (core.js:14187) at execEmbeddedViewsAction (core.js:14145) at checkAndUpdateView (core.js:13837) at callViewAction (core.js:14187) at execEmbeddedViewsAction (core.js:14145) at checkAndUpdateView (core.js:13837) at callViewAction (core.js:14187)
So, here's my component html file with the problem spot.
<div class="panel-body" *ngIf="employee">
<form (ngSubmit)="onSubmit()">
......
<div class="col-md-6">
<div class="form-group" >
<label for="PositionName">Position:</label>
<select *ngIf="positions" class="form-control" id="PositionName" name="PositionName" [(ngModel)]="employee.Position.PositionName" >
<option *ngFor="let u of positions" [value]="u.PositionName" >{{u.PositionName}}</option>
</select>
</div>
</div>
.....
<input type="submit" class="btn btn-primary pull-right" value="Update Employee" />
</form>
</div>
I have no idea why it's not letting me to update my API. If I remove this Position field everything works fine e.g. I can update first name, last name etc.
What I've tried
1) *Posting ngIf in several spots
2) Using elvis operator
3) Rewriting code several times
I'm seriously stuck, please help!
here's some files that I'm using.
employee.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs/Observable";
import { Employee } from "./data/employee";
import { EmployeeRaw } from "./data/employeeRaw";
@Injectable()
export class EmployeeService {
private url = "https://eanton-teams-api-web422.herokuapp.com";
constructor(private http:HttpClient) { }
getEmployees() : Observable<Employee[]> {
return this.http.get<Employee[]>(`${this.url}/employees`);
}
getEmployee(id) : Observable<EmployeeRaw[]> {
return this.http.get<EmployeeRaw[]>(`${this.url}/employee/` + id);
}
saveEmployee(EmployeeRaw) : Observable<any>{
return this.http.put<any>(this.url + '/employee/' + EmployeeRaw._id, EmployeeRaw);
}
}
employee.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { EmployeeRaw } from './data/employeeRaw' ;
import { Position } from './data/position' ;
import { EmployeeService } from './employee.service' ;
import { PositionService } from './position.service' ;
import { LogService } from './log.service' ;
@Component({
selector: 'app-employee',
templateUrl: './employee.component.html',
styleUrls: ['./employee.component.css']
})
export class EmployeeComponent implements OnInit {
employee: EmployeeRaw;
positions: Position[];
constructor( private route: ActivatedRoute,
private e : EmployeeService,
private p : PositionService) { }
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
this.e.getEmployee(id).subscribe( employee => {
this.employee = employee[0];
console.log(this.employee);
//this.hireDate = employee[0].HireDate.format('LL');
});
//{{employee.HireDate | amDateFormat:'LL'}}
this.p.getPositions().subscribe( positions => {
this.positions = positions;
console.log(this.positions);
});
//DEBUG
console.log(this.route);
console.log(id);
//console.log(now);
//console.log( this.route.params.id.toString());
} //ngOnInit
onSubmit(){
this.e.saveEmployee(this.employee)
.subscribe( employee => this.employee = employee );
console.log(this.employee);
}
}
data/employeeRaw.ts
export class EmployeeRaw {
_id: string;
FirstName: string;
LastName: string;
AddressStreet: string;
AddressState: string;
AddressCity: string;
AddressZip: string;
PhoneNum: string;
Extension: number;
Position: string;
HireDate: string;
SalaryBonus: number;
__v: number;
}
data/position.ts
export class Position {
_id: string;
PositionName: string;
PositionDescription: string;
PositionBaseSalary: number;
__v: number;
}