Although I found a workaround, I'm still intrigued to understand the root cause of this issue. This problem arose while working on a project using Angular 7.
The issue was with sorting an array of objects in a service and then passing that sorted array through a subject to a component. Strangely, the component always received an unsorted array, even though the data was provided from a server via websocket.
In summary, the code structure looked like this:
private sortedData: Data[] = [];
private dataSubject= new BehaviorSubject<Data[]>([]);
// The component subscribes to this observable
public data$ = this.dataSubject.asObservable();
public getData() { // Called from the component class
this.apiService('command', this.callback)
}
private callback = (err: any, data: Object[]): void => {
if (err) {
// Error handling code (not relevant to the issue)
} else {
this.sortedData = data.sort((a,b) => a.order - b.order);
this.dataSubject.next(this.sortedData);
}
}
I attempted various solutions including:
- Assigning the value of data to a temporary variable using
Object.assign([],data);
and manipulating the temp - Adding a
setTimeout(()=> this.dataSubject.next(this.sortedData), 500)
- Modifying the
apiService
to return anObservable
instead of using a callback - Creating my own sorting function
- Combining all of the above approaches
Despite trying these methods, none of them resolved the issue. When using ng.probe()
in the dev console to inspect the array in the service, it was evident that the list remained unsorted.
Interestingly, when I commented out
this.dataSubject.next(this.sortedData);
, the array suddenly became sorted.
To resolve this, I added a getter for the sortedData
property and eliminated the use of BehaviorSubject
.
While we managed to address this problem, the underlying cause remains a mystery to me.
EDIT
A simplified version of the problematic code can be viewed here. Although I couldn't reproduce our specific issue here, you'll be able to grasp the structure more clearly. The only difference between the example and our application is the utilization of Socket.io within the ApiService
.
Even though the problem was resolved, I am keen to uncover what led to this unexpected behavior.