Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating an element in a observable list #150

Closed
sbitproz opened this issue Dec 30, 2020 · 5 comments
Closed

Updating an element in a observable list #150

sbitproz opened this issue Dec 30, 2020 · 5 comments

Comments

@sbitproz
Copy link

Thank you for this awesome library.

Reviewing your example https://react-rxjs.org/docs/tutorial/github-issues I can see that there's a good example of requesting a list of items form https://api.github.com/repos/${org}/${repo}/issues?per_page=25&page=${page}.

currentRepoAndPage$ is a merge of 2 source observables currentRepo$ and pageSelected$. When any of these source Subjects emit a new value

 currentRepoAndPage$.pipe(
    switchMap(({ page, repo, org }) =>
      getIssues(org, repo, page).pipe(startWith(SUSPENSE))
    )
  )

will re-execute.

The question; if I had an observable with a list of issues and I wanted to update one of the issues in the list, what would this look like? Would I update the item in the list from the component and call a function to push the new list into the Subject?

I also wondered if we could use BehaviorSubject instead of Subject?

@sbitproz
Copy link
Author

sbitproz commented Dec 30, 2020

So rethinking this question, it appears quite obvious with streams that I must update the array and update Subject with the next data item.

However a clarification on I also wondered if we could use BehaviorSubject instead of Subject? might be useful.

@sbitproz
Copy link
Author

However I would like to know if we can use BehaviorSubject instead of Subject. The use case might be you have a list of items and want to add a new item to the end of the list. In keeping the business logic in the store files, you might want to call a simple no parameter function to add an new item to the end of the list. With a BehaviorSubject enables you to use the last emitted value like so:

const subject: BehaviorSubject<string> = new BehaviorSubject(["a","b","c"]); 
cons newListItem = () => {
   subject.next([...subject.value, "d"])
}

@josepot
Copy link
Member

josepot commented Jan 1, 2021

Hi @sbitproz

Thanks for your kind words and for your interest in this library. Also, sorry that it took me a while to get back to you, I'm trying to take a break during these days 🙂

This is a very interesting question. As you already know, there are many different ways to accomplish this and using a BehaviorSubject is one of them, yes. However, generally speaking, I'm not a huge fan of using BehaviourSubjects and I rather instead defining different streams for the different events that take place and then defining streams that derive from the stream-events. Meaning that in the case of a list that has to be updated, I would probably rather using scan instead of using a BehaviourSubject. But that, of course, it's just the way that I like to work with streams, so please don't read too much into it.

One thing to take into account, though, is that one of the purposes of this library is to help at avoiding memory-leaks. Meaning that if the library is used as it's intended, if a stream stops having subscribers then its state gets disposed. This section of the docs tries to explain this a bit better. However, if we were using BehaviourSubject instead of scaning stateless streams, then we could be inadvertently generating memory leaks, because even when there are no subscribers the BehaviourSubject will keep its latest state around. This is to say that it really depends on your use case, but that as a general recommendation I rather not to promote the pattern that you are suggesting.

I hope that this answers your question.

PS: I've seen that you have opened another issue. I don't have time right now to look at it, but I check it out as soon as I have a chance: probably in the next few days or so 🙂

@sbitproz
Copy link
Author

sbitproz commented Jan 1, 2021

Hi @josepot

Totally grateful for message, on new years day no less...

I like the way you've approached the solution with streams. I've applied your todo example with my state solution - but now I think I might adapt a little more to my use case. However worth noting I believe it introduces a higher level of complexity than using BehaviorSubjects. But maybe it's just another way of approaching the problem that I'm less familiar with.

Although I understand that BehaviorSubject cache's the last emitted value, I'm not sure that will produce a leak. In reality it's just single BehaviorSubject instance representing the state with a cache which will be overwritten.

I freely admit, it maybe be down to my lack of understanding of what's going on under the hood.

You have answered my question and I've read most of the library documentation, just wanted to soundboard the idea (BehaviorSubject). Really appreciate your help.

@josepot
Copy link
Member

josepot commented Jan 17, 2021

However worth noting I believe it introduces a higher level of complexity than using BehaviorSubjects. But maybe it's just another way of approaching the problem that I'm less familiar with

This library wants to promote a mental model where we avoid mutating state directly, because the we want to be able to define the dynamic behavior of the state at the time of its declaration. Therefore, if we adhere to this mental model, then we should try to use Subjects only for capturing external events, not as a means for mutating the state. This is indeed a quite radical mental-shift, but based in our experience, this mental model ends-up generating code that's less complex and easier to maintain.

I'm going to close this issue, because as you said, I have already answered your question. However, feel free to keep commenting on it after it's closed. Thanks!

@josepot josepot closed this as completed Jan 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants