Replies: 5 comments 2 replies
-
In my opinion I think this is same as #5398 (comment) and it's caller's responsibility to protect mutation. |
Beta Was this translation helpful? Give feedback.
-
a) RxJS should be protecting the pushed value to the Behavior Subject to not be changed unless you want side effects through your whole code. You can see, in my tiny example, how easy is to mess the value and how other functions using getValue can then get side-effected. This would be a big hole in the design of RxJS itself, so I don't really buy the idea this is an expected "feature". b)However, lets believe this is the "expected" behavior and any function/method can "mess" (sorry I can't find a better word) the value stored in a Subject through reference as the repro case is showing, then RxJS should be sending to all the "subscriptions" the change done by reference so they can react accordingly. Current implementation is not doing a) nor b). |
Beta Was this translation helpful? Give feedback.
-
I am personally not in agreement for both, but probably other team member might have different opinions so I'll leave this as opened. However, at least I do not think this is a known bug to be filed, so moving this as into discussions for further update. |
Beta Was this translation helpful? Give feedback.
-
Then I am open to ideas. However my bet is that right now developers using "getValue()" or ".value" are probably mutating by reference the values stored in the Subjects and scratching their heads when another method returns a "mutated" value from the Subject.value. |
Beta Was this translation helpful? Give feedback.
-
We can't really do this. If you're worried about mutations, you could always use a library like Immer and next those into the subject. The problem is, we'd have to perform deep copies of objects in order to really protect completely. Deep copying is pretty slow and very inefficient. Also then the expectation is would be doing it everywhere. Like
|
Beta Was this translation helpful? Give feedback.
-
Bug Report
Current Behavior
Subjects values can be easily messed up via getValue() or subject.value since they are returning references. Imho, by design, the only way a Subject value should be able to be modified is through Subject.next(). Otherwise the Subject.value can be modified by a function1() and hence a function2() can obtain inconsistent values.
Expected behavior
RxJS should prevent Subject.values to be modified by anone but a "next" push.
Reproduction
This reproduction example shows 2 Test Cases.
First test case is just reading the subject.value, manipulating the returned value and as a side effect modifying subject value (and probably totally unnoticed for the developer due the "sticky" references Javascript has).
Worst thing is that a second function, which could live in a different file/method, now is seeing a wrong Subject value and outputting a wrong result.
Second test case is showing how subject.getValue() is really returning also a reference, so the behavior is exactly the same. (Just checking if it was making any difference really)
RxJS should protect the value/s being stored in the Subjects. If a value was pushed to a Subject, no one should be able to modify such value. This is imho critical in a language, as Javascript is, where references are so sticky.
https://stackblitz.com/edit/rxjs-mess-subject?file=index.ts
Environment
Latest RXJS, provided in the stackblitz.
Possible Solution
If, for retrocompatibility, subject.value and getValue() are decided to keep returning references, then I would suggest to create a new getDeepValue() method which returns a deep clone to avoid the mess created in the example and heavily recommend to use getDeepValue() in documentation.
Beta Was this translation helpful? Give feedback.
All reactions