I have a service with a RXJS subject and i am assigning data to subject inside constructor doing an api call. This subject I am subscribing in a component template. Though the data is provided to the subject, it is not emitting immediately the first time.
interface Employee {
employee_age: number;
employee_name: string;
employee_salary: number;
id: string;
profile_image: string;
}
@Injectable({
providedIn: "root",
})
export class EmployeeService {
employeesSub = new Subject<Employee[]>();
employees: Employee[];
constructor(private http: HttpClient) {
this.api().subscribe((res) => {
this.employees = res.data;
this.employeesSub.next(this.employees);
});
}
getEmployees(){
this.employeesSub.next(this.employees);
}
addEmployee(name,age,salary) {
this.employees.unshift({
id:(this.employees.length + 1).toString(),
employee_age: age,
employee_name: name,
employee_salary: salary,
profile_image: ""
});
this.employeesSub.next(this.employees);
}
api() {
return this.http
.get<any>(environment.employeeUrl)
.pipe(map((data) => data.items));
}
}
Code in template
<h2>List</h2>
<div style="display: flex;"></div>
<table>
<tr *ngFor="let item of employeeService.employeesSub | async">
<td>{{ item.employee_name}}</td>
<td>{{ item.employee_age}}</td>
<td>{{ item.employee_salary}}</td>
</tr>
</table>
I am reassigning data by calling the getEmployees() function after 200ms and it is working. Any idea why this is happening.
You need to switch to a BehaviorSubject.
The service gets initialized before the component does, so it's emitting the value before the component gets to subscribe. Since a Subject doesn't hold a value, the component doesn't get anything. By swapping to a Behavior subject, you can subscribe to it and immediately get the latest value.
The accepted answer here describes the difference been a
Subject
and aBehaviorSubject
well.