I have an angular 6 app and I originally set up my backend with a rest api, but i'm starting to convert parts to use socket.io.
When I return the data from my rest api the following works:
this.http.get(api_url + '/versions/entity/' + entityId).pipe(
mergeMap((versions:IVersion[]) => versions),
groupBy((version:IVersion) => version.type),
mergeMap(group => group.pipe(
toArray(),
map(versions=> {
return {
type: group.key,
versions: versions
}
}),
toArray()
)),
reduce((acc, v) => acc.concat(v), [])
);
The express route:
router.get('/entity/:entityId', (req, res) => {
const entityId = req.params.entityId;
Version.getVersionsByEntity(entityId, (err, versions) => {
if (err) {
res.json({success: false, msg: err});
} else {
res.json(versions);
}
});
});
Which gets the data from my mongo database with mongoose:
export function getVersionsByEntity(entityId, callback) {
console.log('models/version - get versions by entity');
Version.find({'entity.entityId': entityId})
.exec(callback);
}
However when I make the exact same call but with socket.io the observable doesn't return anything. I'm guessing its because it never completes? Does an http call send a 'complete' message when the data is successfully transferred?
The sockets are sent from this service:
getVersionsByEntity(entityId): Observable<IVersion[]> {
// create observable to list to refreshJobs message
let observable = new Observable(observer => {
this._socketService.socket.on('versionsByEntity', (data) => {
observer.next(data);
});
});
this._socketService.event('versionsByEntity', entityId);
return <Observable<IVersion[]>> observable;
}
Which calls the same mongoose function from the server.
The observable returned from (socket) service does actually contain data, it's only once I add the toArray()
functions that it never prints anything when I subscribe..
Could someone help me fix this and also explain the theory behind this? Is it not completing? Does http send a 'completed' message with Angular?
EDIT: I've created a simple stackblitz which is doing what I want but I want to remove the take(1) from the _dataService since I may want to update the data so I want to keep the observable open - https://stackblitz.com/edit/rxjs-toarray-problem
EDIT 2: I'm close by replacing toArray with the scan operator but it seems to be emitting twice for the array. reduce() emits the correct data but seems to only emit on complete (like toArray) so its no better - https://stackblitz.com/edit/rxjs-toarray-problem-tpeguu