diff --git a/src/domain/session/room/timeline/TilesCollection.js b/src/domain/session/room/timeline/TilesCollection.js index 2a53c9d4..f8c55e3a 100644 --- a/src/domain/session/room/timeline/TilesCollection.js +++ b/src/domain/session/room/timeline/TilesCollection.js @@ -143,6 +143,10 @@ export class TilesCollection extends BaseObservableList { } onUpdate(index, entry, params) { + // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it + if (!this._tiles) { + return; + } const tileIdx = this._findTileIdx(entry); const tile = this._findTileAtIdx(entry, tileIdx); if (tile) { diff --git a/src/observable/list/ConcatList.js b/src/observable/list/ConcatList.js index a51ddd55..d395e807 100644 --- a/src/observable/list/ConcatList.js +++ b/src/observable/list/ConcatList.js @@ -33,10 +33,7 @@ export class ConcatList extends BaseObservableList { } onSubscribeFirst() { - this._sourceUnsubscribes = []; - for (const sourceList of this._sourceLists) { - this._sourceUnsubscribes.push(sourceList.subscribe(this)); - } + this._sourceUnsubscribes = this._sourceLists.map(sourceList => sourceList.subscribe(this)); } onUnsubscribeLast() { @@ -62,6 +59,11 @@ export class ConcatList extends BaseObservableList { } onUpdate(index, value, params, sourceList) { + // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it + // as we are not supposed to call `length` on any uninitialized list + if (!this._sourceUnsubscribes) { + return; + } this.emitUpdate(this._offsetForSource(sourceList) + index, value, params); } diff --git a/src/observable/list/MappedList.js b/src/observable/list/MappedList.js index 0bc4065a..1aed299f 100644 --- a/src/observable/list/MappedList.js +++ b/src/observable/list/MappedList.js @@ -48,6 +48,10 @@ export class MappedList extends BaseObservableList { } onUpdate(index, value, params) { + // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it + if (!this._mappedValues) { + return; + } const mappedValue = this._mappedValues[index]; if (this._updater) { this._updater(mappedValue, params, value); diff --git a/src/observable/list/SortedMapList.js b/src/observable/list/SortedMapList.js index 27003cba..babf5c35 100644 --- a/src/observable/list/SortedMapList.js +++ b/src/observable/list/SortedMapList.js @@ -70,6 +70,10 @@ export class SortedMapList extends BaseObservableList { } onUpdate(key, value, params) { + // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it + if (!this._sortedPairs) { + return; + } // TODO: suboptimal for performance, see above for idea with BST to speed this up if we need to const oldIdx = this._sortedPairs.findIndex(p => p.key === key); // neccesary to remove pair from array before diff --git a/src/observable/map/FilteredMap.js b/src/observable/map/FilteredMap.js index 71b7bbeb..8e936f5d 100644 --- a/src/observable/map/FilteredMap.js +++ b/src/observable/map/FilteredMap.js @@ -82,6 +82,10 @@ export class FilteredMap extends BaseObservableMap { } onUpdate(key, value, params) { + // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it + if (!this._included) { + return; + } if (this._filter) { const wasIncluded = this._included.get(key); const isIncluded = this._filter(value, key); diff --git a/src/observable/map/JoinedMap.js b/src/observable/map/JoinedMap.js index e5d0caa7..7db04be1 100644 --- a/src/observable/map/JoinedMap.js +++ b/src/observable/map/JoinedMap.js @@ -48,6 +48,10 @@ export class JoinedMap extends BaseObservableMap { } onUpdate(source, key, value, params) { + // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it + if (!this._subscriptions) { + return; + } if (!this._isKeyAtSourceOccluded(source, key)) { this.emitUpdate(key, value, params); } diff --git a/src/observable/map/MappedMap.js b/src/observable/map/MappedMap.js index 48a1d1ad..ec33c4dd 100644 --- a/src/observable/map/MappedMap.js +++ b/src/observable/map/MappedMap.js @@ -49,6 +49,10 @@ export class MappedMap extends BaseObservableMap { } onUpdate(key, value, params) { + // if an update is emitted while calling source.subscribe() from onSubscribeFirst, ignore it + if (!this._mappedValues) { + return; + } const mappedValue = this._mappedValues.get(key); if (mappedValue !== undefined) { // TODO: map params somehow if needed?