Reputation: 113
I am working in angular 7
I have to perform simple task there is one component teacher-details
which shows the list of registered teacher in a table format (Getting this from database using node js) and also update the table when new teacher record is added, I also have a teacher.service.ts
which contain teacher array and contain a method getTeacher()
and addTeacher()
so teacher component using this service to display the record.
My problem is when I enter new record of teacher its not getting update to the UI/page but when I reload the it gets updated, But I want to update the page dynamically as soon as I enter the record.
teacher-details.component.ts
@Component({
selector: 'app-teacher-details',
templateUrl: './teacher-details.component.html',
styleUrls: ['./teacher-details.component.css']
})
export class TeacherDetailsComponent implements OnInit {
private teachers: Teacher[] = []
constructor(private teacherServ: TeachersService, private auth: AuthService) {
}
ngOnInit() {
this.auth.getTeacherRecords().subscribe(
res => this.teachers = res.message,
err => console.log(err)
),
this.teachers = this.teacherServ.getTeachers();
}
}
teacher.service.ts
@Injectable()
export class TeachersService {
teacherChanged = new EventEmitter<Teacher[]>();
private teachers: Teacher[] = [];
constructor(private auth: AuthService) {}
getTeachers() {
return this.teachers;
}
addTeachers(teacher: any) {
this.auth.addTeacher(teacher)
.subscribe(
res => console.log(res),
err => console.log(err)
);
this.teachers.push(teacher);
}
}
I am also sharing my auth service which gets the details from the database.
@Injectable()
export class AuthService {
private addTeacherUrl = "http://localhost:3000/api/addTeacher"
private getTeacherRecordsUrl = "http://localhost:3000/api/getTeacherRecords"
addTeacher(teacherRecord: any) {
console.log("Inside addTEacher servvice")
console.log(teacherRecord)
return this.http.post<any>(this.addTeacherUrl, teacherRecord)
}
getTeacherRecords() {
return this.http.get<any>(this.getTeacherRecordsUrl, {
observe: "body"
})
}
}
teacher-details.component.html
<div class="card">
<div class="card-header border-0">
<div class="row align-items-center">
<div class="col">
<h3 class="mb-0">Teacher Details</h3>
</div>
</div>
</div>
<div class="table-responsive">
<!-- Projects table -->
<table class="table align-items-center table-flush">
<thead class="thead-light">
<tr>
<th scope="col">Teacher Name</th>
<th scope="col">Teacher subject</th>
<th scope="col">Teacher branch</th>
<th scope="col">Teacher Semester</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let teachers of teachers">
<th scope="row">
{{teachers.fullName}}
</th>
<td>
{{teachers.subject}}
</td>
<td>
{{teachers.branch}}
</td>
<td>
{{teachers.semester}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
I am very confused what should I do, Please help me out here.
UPDATE:-
I did the following changes according to the suggestion:
auth.service.ts
@Injectable()
export class AuthService {
private addTeacherUrl = "http://localhost:3000/api/addTeacher"
private getTeacherRecordsUrl = "http://localhost:3000/api/getTeacherRecords"
subject = new Subject<Teacher[]>();
teachers: Teacher[]
constructor(private http: HttpClient) { }
addTeacher(teacherRecord: any) {
console.log("Inside addTEacher servvice")
console.log(teacherRecord)
this.teachers.push(teacherRecord)
this.subject.next(this.teachers)
return this.http.post<any>(this.addTeacherUrl, teacherRecord)
}
getTeacherRecords() {
return this.http.get<any>(this.getTeacherRecordsUrl, {
observe: "body"
})
}
}
teacher-details.component.ts
@Component({
selector: 'app-teacher-details',
templateUrl: './teacher-details.component.html',
styleUrls: ['./teacher-details.component.css']
})
export class TeacherDetailsComponent implements OnInit {
teachers: Teacher[];
constructor(private teacherServ: TeachersService, private auth: AuthService) {
}
ngOnInit() {
this.auth.getTeacherRecords().subscribe(
res => this.teachers = res.message,
err => console.log(err)
);
this.auth.subject.subscribe(
res => console.log(res),
err => console.log(err)
)
}
}
Still data getting updated after reloading the page
Thanks.
Upvotes: 2
Views: 726
Reputation: 2283
The getTeachers()
method in your service is synchronous and will return values only when it is called.
What you probably need is a Subject
that emits values whenever you tell it to.
I believe something like this in your service:
import { Subject } from 'rxjs';
const subject = new Subject<Teacher[]>();
addTeacher(teacherRecord: any) {
console.log("Inside addTEacher servvice")
console.log(teacherRecord)
//HERE YOU ADD THIS
this.teachers.add(teacherRecord);
this.subject.next(this.teachers);
return this.http.post<any>(this.addTeacherUrl, teacherRecord)
}
and in your ts file you initialize like this:
ngOnInit() {
this.auth.getTeacherRecords().subscribe(
res => this.teachers = res.message,
err => console.log(err)
),
this.auth.subject.subscribe(
res => this.teachers = res.message,
err => console.log(err)
),
}
Also, remember to unsubscribe on OnDestroy
to avoid memory leaks.
Upvotes: 2
Reputation: 11
You subscribe to the getTeacherRecords()
in onInit()
.
This method returns an observable which is not getting updated when you do something on the page because a new HTTP request is not send.
The issue is that you use an observable that does not emit other values.
As I can see, you use EventEmitter
in teachers service.
You should subscribe to it in your component like this:
ngOnInit() {
this.teachers = this.teacherServ.teacherChanged.subscribe(
teachers => this.teachers = teachers
);
}
Note You should unsubscribe
in ngOnDestroy
- it's best practice.
Do not forget to emit teachers after addition:
addTeachers(teacher: any) {
this.auth.addTeacher(teacher)
.subscribe(
res => console.log(res),
err => console.log(err)
);
this.teachers.push(teacher);
// note that line
this.teacherChanged.emit(this.teachers);
}
This should work, hope that hepls!
Upvotes: 1