Reputation: 958
I have a problem like this. I am creating a web application with angular 5, Nodejs and MongoDB. To send data to the database I have created an HTML file like this.
<div class="row">
<div class="col s12 m6">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<div class="row">
<div class="col s5">
<form #employeeForm="ngForm" (ngSubmit)="onSubmit(employeeForm)">
<input type="hidden" name="_id" #_id="ngModel" [(ngModel)]="employeeService.selectedEmployee._id">
<div class="row">
<div class="input-field col s12">
<input type="text" name="name" #name="ngModel" [(ngModel)]="employeeService.selectedEmployee.name" placeholder="Enter full name" required>
<label>Name :
<label class="red-text">*</label>
</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input type="text" name="position" #name="ngModel" [(ngModel)]="employeeService.selectedEmployee.position" placeholder="Eg : Snr. Developer">
<label>Position :</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input type="text" name="office" #name="ngModel" [(ngModel)]="employeeService.selectedEmployee.office" placeholder="Enter office location">
<label>Office :</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<input type="text" name="salary" #name="ngModel" [(ngModel)]="employeeService.selectedEmployee.salary" placeholder="Salary per annum">
<label>Salary :</label>
</div>
</div>
<div class="row">
<div class="input-field col s12">
<button class="btn btn-custom right" type="button" (click)="resetForm(employeeForm)">Reset</button>
<button class="btn btn-custom right" type="submit" [disabled]="!employeeForm.valid">Submit</button>
</div>
</div>
</form>
</div>
<div class="col s7">
</div>
</div>
</div>
</div>
</div>
</div>
To send data to the backend I have created a method like this in the components.ts file. This the code in that file.
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { EmployeeService } from '../shared/employee.service';
import { Employee } from '../shared/employee';
declare var M: any;
@Component({
selector: 'app-employee',
templateUrl: './employee.component.html',
styleUrls: ['./employee.component.css'],
providers: [EmployeeService]
})
export class EmployeeComponent implements OnInit {
constructor(private employeeService: EmployeeService) { }
ngOnInit() {
this.resetForm();
this.refreshEmployeeList();
}
resetForm(form?: NgForm) {
if (form) {
form.reset();
this.employeeService.selectedEmployee = {
_id: '',
name: '',
position: '',
office: '',
salary: null
};
}
}
onSubmit(form: NgForm) {
if (form.value._id === '') {
this.employeeService.postEmployee(form.value).subscribe((res) => {
this.resetForm(form);
M.toast({ html: 'Saved successfully', classes: 'rounded' });
});
}
}
refreshEmployeeList() {
this.employeeService.getEmployeeList().subscribe( (res) => {
this.employeeService.employees = res as Employee[];
});
}
onEdit(emp: Employee) {
this.employeeService.selectedEmployee = emp;
}
onDelete(_id: string, form: NgForm) {
if (confirm('Are you sure to delete this record ?') === true) {
this.employeeService.deleteEmployee(_id).subscribe((res) => {
this.refreshEmployeeList();
this.resetForm(form);
M.toast({ html: 'Deleted successfully', classes: 'rounded' });
});
}
}
}
And my service file is like this.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import { Employee } from './employee';
@Injectable()
export class EmployeeService {
selectedEmployee: Employee;
public employees: Employee[];
readonly baseURL = 'http://localhost:3000/employees';
constructor(private http: HttpClient) { }
postEmployee(employee: Employee) {
return this.http.post(this.baseURL, employee);
}
getEmployeeList() {
return this.http.get(this.baseURL);
}
putEmployee(emp: Employee) {
return this.http.put(this.baseURL + `/${emp._id}`, emp);
}
deleteEmployee(_id: string) {
return this.http.delete(this.baseURL + `/${_id}`);
}
}
My app.module.ts file is like this.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { EmployeeComponent } from './employee/employee.component';
@NgModule({
declarations: [
AppComponent,
EmployeeComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
And my employee model class looks like this.
export class Employee {
public _id: string;
public name: string;
public position: string;
public office: string;
public salary: number;
}
When I hit ng serve it is giving me an error like this.
ERROR TypeError: Cannot read property '_id' of undefined
at Object.eval [as updateDirectives] (EmployeeComponent.html:8)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:14697)
at checkAndUpdateView (core.js:13844)
at callViewAction (core.js:14195)
at execComponentViewsAction (core.js:14127)
at checkAndUpdateView (core.js:13850)
at callViewAction (core.js:14195)
at execComponentViewsAction (core.js:14127)
at checkAndUpdateView (core.js:13850)
at callWithDebugContext (core.js:15098)
Yesterday also I asked this question I think my explanation was not clear. So Today I am asking it with more description. Can someone help me to solve this issue? Thank You Very much.
Upvotes: 0
Views: 892
Reputation: 1042
I hope this helps, but typescript still transpiles to javascript, which really has no way to know that the currentemployee is a class, which is why it says it cannot find the I'd field. However, you can allocate the object which WILL have an I'd field, yet I dont see any place where this is occurring. I think the angular binding is not working because you have only declared, but not initialized the object.
Maybe allocate the employee..
public currentEmployee : Employee = new Employee();
Please forgive any mistakes, just a general idea to show, typing this at 3am on my android in bed unable to sleep.
Upvotes: 0
Reputation: 3574
Try this, though it will generalize your object, it will work:
In your EmployeeService, declare selectedEmployee as below
selectedEmployee: any = {};
Upvotes: 1