'Angular Pipe and Map are getting called again from a different function
I have a table where I display a list of assets which are stored in an Observable.
For each asset, there is a delete button that deletes the asset from the table.
I also have a drop-down where the user can add assets to the table (the assets deleted from table reappear in the drop-down too).

The following is the delete function that simply filters the Observable (assets$), and add the deleted asset into the drop-down list, I also have other lists (assetsToDelete and assetsToAdd for adding to the database).
onDelete(a: any) {
const form: any = {
assetId: a.id,
scenarioId: this.data.id,
};
this.assets$.subscribe(data => console.log(data));
this.assets$ = this.assets$.pipe(
map((asset: any) => {
console.log(asset);
const assets = asset.filter((assett: any) => assett.id !== a.id);
return assets;
})
);
// this.assets$.subscribe(data => {
// return data.filter((assett: any) => assett.id !== a.id);
// })
this.assets$.subscribe(data => console.log(data));
this.dropdownList = this.dropdownList.concat([a]);
this.assetsToDelete.push(form);
this.assetsToAdd = this.assetsToAdd.filter((id: any) => id !== a.id);
}
My Add function is triggered when the user presses on the "Add Selected Assets" button:
addAssetsToScenario() {
this.edit = true;
if (this.selectedItems.length === 0) {
Swal.fire('No Assets', 'Please select asset(s) to add', 'warning');
} else {
const ids: any = this.selectedItems.map(curr => (curr as any).id);
this.assetsToAdd.push.apply(this.assetsToAdd, ids);
this.assets$ = this.assets$.pipe(
map((assets: any) => {
for (let i = 0; i < this.selectedItems.length; i++) {
assets.push(this.selectedItems[i]);
this.dropdownList = this.dropdownList.filter(
asset => asset.id !== (this.selectedItems[i] as any).id
);
this.assetsToDelete = this.assetsToDelete.filter(
(asset: { assetId: any }) => {
return asset.assetId !== (this.selectedItems[i] as any).id;
}
);
}
this.selectedItems = [];
return assets;
})
);
}
}
I am getting all of the selected items in the drop-down and pushing them into the Observable (assets$). There are some other functions to filter the drop-down and the assetsToDelete lists.
My problem is that whenever I delete one of the assets it gets deleted successfully. However, when I then try to add any asset from the drop down menu, nothing happens. I tried to track the issue and it seems that the pipe(map()...) in the "onDelete" function is being called whenever I try to use it again in any function such as the "addAssetsToScenario" function.
I am not sure why this is happening, as I am not calling the onDelete function when adding the assets.
Solution 1:[1]
When you do this:
this.assets$ = this.assets$.pipe(...)
you are chaining observables. You are piping the output of the existing $asset observable to a new observable and storing the new observable in assets$. So when:
- You call
onDeleteyou are piping the output of the existingassets$observable to a new observable that you put intoassets$. - You call
addAssetsToScenarioyou chain another new observable that takes the output of the existingassets$observable created in step 1 and again storing this new observable inassets$. - subscribing to
assets$after step 2 will pipe the original observable to the map operator created in step 1 and then pipe the output of that to the map operator created in step 2.
So yes, the map from onDelete will be called along with the map from addAssetsToScenario depending on when you have subscribed to assets$. If you call these functions multiple times you will keep adding observables to the chain.
I suggest you look for a tutorial on rxjs to get a better understanding of observables, subscriptions and operators.
Solution 2:[2]
Using this.assets$.subscribe(data => console.log(data)); doesn't just print the array, it calls every operation you piped to it so far. The bellow code is an infinite loop.
function removeElement() {
assetsObservable = assetsObservable.pipe(
map((asset: any[]) => {
assetsObservable.subscribe((a) => console.log(a));
return asset.filter((e) => e < 4);
})
);
}
removeElement();
assetsObservable.subscribe((a) => console.log(a));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Hopey One |
| Solution 2 | anthony yaghi |
