THIS Flow Mistake Will Lead to Bugs in Your Code (StateFlow & Reactive Programming)

Flows are an awesome framework for reactive programming. However, to get the most out of them you have to understand the core concepts of reactivity. In this video I'll talk about some common mistakes.
⭐ Get certificates for your future job
⭐ Save countless hours of time
⭐ 100% money back guarantee for 30 days
⭐ Become a professional Android developer now:
pl-coding.com/premium-courses...
💻 Let me be your mentor and become an industry-ready Android developer in 10 weeks:
pl-coding.com/drop-table-ment...
Subscribe to my FREE newsletter for regular Android, Kotlin & Architecture advice!
pl-coding.com/newsletter
Join this channel to get access to perks:
/ @philipplackner
Join my Discord server:
/ discord
Regular programming advice on my Instagram page: / _philipplackner_
Checkout my GitHub: github.com/philipplackner
You like my free content? Here you can buy me a coffee:
www.buymeacoffee.com/philippl...

Пікірлер: 83

  • @OlafAchthoven
    @OlafAchthoven Жыл бұрын

    You actually showed the perfect reason to name the lambda parameters. Should be a good practice to not work with 'it'.

  • @s-w

    @s-w

    Жыл бұрын

    Yep, but I still use "it" when it's clear and there are no nested "its".

  • @ChrisAthanas
    @ChrisAthanas Жыл бұрын

    Phillipp, it would be helpful to us if you turned on `inlay hints` so we can see the types of your variable as opposed to having to manually select "type info"

  • @makzimalist
    @makzimalist Жыл бұрын

    As usual, great video, very informativ, well prepared and top quality. Thanks a lot ...!

  • @laszloforgacs8210
    @laszloforgacs8210 Жыл бұрын

    Very informative, I dig the recent topics on the channel!

  • @abhimanyu.n14
    @abhimanyu.n14 Жыл бұрын

    To add on, we can use a lot of methods for derived state in ViewModel like map, combine, filter, reduce, zip, fold, flatmap, etc as per the use-case.

  • @eduardoscaranari5262
    @eduardoscaranari52628 ай бұрын

    this is fantastic. thanks for such amazing content Philipp. 🤝

  • @s-w
    @s-w Жыл бұрын

    Thank you for the tips as usual!

  • @foivosstamopoulos4106
    @foivosstamopoulos410610 ай бұрын

    Great tutorial as always!!

  • @skarloti
    @skarloti Жыл бұрын

    mutableStateListOf() instead MutableStateFlow(emptyList()> unless I want to use sealed class ResultOf and get statuses for Loading, Error, Succes. Only in this case would I use Flows.

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    1. You can't assume someone is using Compose 2. Even for Compose, I don't recommend using Compose state in a VM directly. Will soon explain in a video why

  • @skarloti

    @skarloti

    Жыл бұрын

    @@PhilippLackner class SnapshotStateList : MutableList, StateObject

  • @ChrisAthanas

    @ChrisAthanas

    Жыл бұрын

    @@skarloti What is this snippet about?

  • @skarloti

    @skarloti

    Жыл бұрын

    @@ChrisAthanas hello, maybe it will become clearer to you visually on the link I am sending you. I hope that's not a problem. The short demo shows how when data in a list is modified, it is updated in the user interface via MVVM. Take a look in row #22: snapshotFlow {} kzread.info/dash/bejne/hISkuruxp9KYqaw.html

  • @EvgenSuit
    @EvgenSuit5 ай бұрын

    An alternative to using combine and 3 different flows is creating just one, which could be represented by a single data class (wrapped in MutableStateFlow), which holds isLoggedIn, chatMessages and users. With this we can utilize the "update" method and only change the fields that require an update

  • @MrVipulLal
    @MrVipulLal Жыл бұрын

    Love your channel

  • @quantumgaming7
    @quantumgaming7 Жыл бұрын

    Really Nice Tips. Thanks for this.

  • @ruavaen
    @ruavaen Жыл бұрын

    Great video. Thanks

  • @datel666
    @datel666 Жыл бұрын

    Great video as always

  • @Guilo583
    @Guilo583 Жыл бұрын

    Thanks for the great tutorial.

  • @ukhanyov
    @ukhanyov Жыл бұрын

    Awesome, thank you

  • @original_anu
    @original_anu Жыл бұрын

    This could be a good hint by IDE. When you are using state.value in operators like combine, suggest using that state in the dependents list Similar useEffect with useState in react.

  • @mark-147
    @mark-147 Жыл бұрын

    Excellent, thanks. Would be interested in some practical use cases where other SharingStarted values are used.

  • @sabuta100
    @sabuta100 Жыл бұрын

    I know Rx is not that popular now that flows are out there, but it would be great if you make a series explaining operators and how to combine them. Your ability to teach and the effort behind that is so incredible that learning such a painful topic as Rx might be, would make it easy to understand. Thanks for all your videos!

  • @tabassumfatima2398
    @tabassumfatima2398 Жыл бұрын

    Best video really like your content 👍

  • @norayrmovsisyan
    @norayrmovsisyan Жыл бұрын

    thank you very much!

  • @GeolseuDeiGamers
    @GeolseuDeiGamers Жыл бұрын

    Awesome!

  • @abdurahmon2827
    @abdurahmon282710 ай бұрын

    Thanks bro you are life saver

  • @valtteri_its_james
    @valtteri_its_james Жыл бұрын

    Mate, you are legend

  • @nguyencodervn
    @nguyencodervn Жыл бұрын

    Thank you

  • @ashwinpatidar2878
    @ashwinpatidar2878 Жыл бұрын

    Thanks you Philipp 👍🔥🤟

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    Welcome!

  • @asadullahilyas
    @asadullahilyas Жыл бұрын

    I was making the same mistake.. I’ll get it fixed tomorrow as soon as I get my hands on that laptop

  • @osisuper98
    @osisuper98 Жыл бұрын

    You keep giving me reasons to no longer use Compose States. Thank you.

  • @mohammedalramlawi691
    @mohammedalramlawi691 Жыл бұрын

    combine is very usefull, I loved it 🤩

  • @TheAndroidFactory
    @TheAndroidFactory Жыл бұрын

    Love combine!

  • @user--10552
    @user--105525 ай бұрын

    thanks a lot.

  • @MyFoenix
    @MyFoenix Жыл бұрын

    Also, as mentioned above, I tried to change flow value in a viewmodel and combine did not fired. It was only fires when items goes from repository for example

  • @LightBueno
    @LightBueno Жыл бұрын

    legend

  • @mustafaammar551
    @mustafaammar551 Жыл бұрын

    you are the best

  • @IoannisAnifantakis
    @IoannisAnifantakis4 ай бұрын

    The old good transformation maps :)

  • @irsathkareem7513
    @irsathkareem7513 Жыл бұрын

    Please make video on exoplayer with compose ui CONTROLS, eagerly waiting

  • @ChrisAthanas

    @ChrisAthanas

    Жыл бұрын

    He has one, look for Spotify Clone

  • @shaiquekhan1185
    @shaiquekhan1185 Жыл бұрын

    what's your studio's theme? looks pretty cool.

  • @omkarpawar1741
    @omkarpawar1741 Жыл бұрын

    can you provide a tutorial about mutablestatelistof with jetpack compose

  • @summerwise
    @summerwise Жыл бұрын

    Hello, could you make a video about navigation with TopBar? I mean how to change topBar title and back button after changing our screen. In xml we can bind our toolbar to navgraph, idk how to do that on jetpack compose in right way.

  • @iga137
    @iga137 Жыл бұрын

    Hi bro, please, make a video about the new logcat in AC)

  • @ChrisAthanas
    @ChrisAthanas Жыл бұрын

    Phillip, bc there was not a github link to the code, I wrote the code you have here into a project. The first example worked fine, but the second example (with the combine) only accepts the initial state for the chatState StateFlow. All additional `user.update{ it + user }` or `chatMessages.update { it + message }` do not emit additional ChatStates via the `combine`. It looks like this doesn't work as described. You should always run your code in these examples to be sure they are working as intended! It seems that the `combine` flow will not be re-triggered unless the values of the StateFlow variables change. Since the `List` does not change (only the contents of list change), the `combine` is never triggered. You will need to wrap the Lists and add a UUID (any random UUID) that indicates the underlying list has changed in order to trigger the `combine` to re-emit a new value. Thats the only way I could get this example to work.

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    I don't get what you mean, I just tried it again and the code is working perfectly fine as intended. A core concept of StateFlow is that it holds a value until it changes, so the collector will not fire until the chat state changes (which is what we want). So in your example, you might've changed the users or chat messages flow's values, but if that change doesn't cause a change in the ChatState (because you might've added a message without adding a user first), your collector will not be triggered. In either way, the combine block will be triggered with every update of the MutableStateFlows (if their value changes).

  • @ChrisAthanas

    @ChrisAthanas

    Жыл бұрын

    @@PhilippLackner Im trying to figure out what is going wrong, because the code I have is the same as your code. I am collecting the `chatState` in the MainActivity (just like the first example), but when I call to the viewmodel to add a user or add a new message, (using an `users.update { user }` mechanism ) the `combine` is not triggered. Is there something special about the `collect` that is needed for the `combine`? Maybe you could include a link to your code so I can check out whats going on, because my code is identical to yours and its definitely not updating.

  • @ChrisAthanas

    @ChrisAthanas

    Жыл бұрын

    I found a clue, it seems that the `combine` operator is executed on a looper, and if you don't give time for it to execute, you will not see the updates. The issue is that I thought it ran in the same coroutine/thread. When I launched the viewModel functions in a separate coroutine, the updates occurred, but they were batched together, so the collect would only see the latest state, not each individual state change, unlike the first example in the video.

  • @MyFoenix

    @MyFoenix

    Жыл бұрын

    Yes, I also tried to change value of my flow in a viewmodel and combine did not fired

  • @czerewacz
    @czerewacz Жыл бұрын

    Phillip the G.O.A.T !!!

  • @GilTheCohen
    @GilTheCohen Жыл бұрын

    Why are you not using mutableStateListOf ?

  • @samstoyroom
    @samstoyroom Жыл бұрын

    What's the difference between map{} and mapLatest{} ?

  • @yeyaanshkit
    @yeyaanshkit Жыл бұрын

    Hi Phillip, please create a fresh Series of Android Development for beginners.. Please the Updated one..

  • @stanleykou5643
    @stanleykou5643 Жыл бұрын

    Wow

  • @MyFoenix
    @MyFoenix Жыл бұрын

    Hi! Did you try to combine more then 5 values? When I tried I got an error about types...

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    at some point, you'll get an array of items since they don't want to create a million overloads of course

  • @MyFoenix

    @MyFoenix

    Жыл бұрын

    @@PhilippLackner but in sorces varargs is used.... and this is popular case, complicated screens can use more then 5 flows...

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    @@MyFoenix yea but you get it as array

  • @pinoy_marites_beh
    @pinoy_marites_beh Жыл бұрын

    I tried exactly what you did in your example @Philipp, but it only updates the second flow (localUser) once, and every time I do something on the "_users" parent flow, the "localUser" flow doesnt get updated..

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    It's only updated if the result (the local user) changes

  • @pinoy_marites_beh

    @pinoy_marites_beh

    Жыл бұрын

    @@PhilippLackner ohh, I see, I thought the premise was any updates "happened" on the "_user" , it will then automatically reflect (updates) to the "localUser"

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    @@pinoy_marites_beh add a println statement in the map block and you should see that it gets updated :) but the collector of localUser will only be called if the value changes

  • @pinoy_marites_beh

    @pinoy_marites_beh

    Жыл бұрын

    @@PhilippLackner Still wrapping my head around when and where should I expect it to be updated though, maybe I'm thinking a different use-case, but anway, thank you Philipp, Great content as always.

  • @cularu1
    @cularu1 Жыл бұрын

    why don't you just filter the list? instead of map and find?

  • @icycleragon

    @icycleragon

    Жыл бұрын

    Filter returns a list and he wanted a specific user

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    Filter would filter the flow, not the list. So with filter you could say that some list emissions are completely dropped

  • @i_Kode
    @i_Kode Жыл бұрын

    I would recommend passing the timeout as first parameter to SharingStarted.WhileSubscribed(), something like 2 seconds. this will ensure that the flow will not stopped and gets recalculated after screen rotation but instead it will stop if the app is in background.

  • @carlosmspk
    @carlosmspk Жыл бұрын

    in that last example, I don't understand why you say "Else we'd have to recalculate everything when any of the parameters changed". Isn't that what's happening anyways? Isn't there a way to also get WHICH of the combined parameters changed? We might be talking about a very long list, and I don't want to recompute the entire thing if another, unrelated variable changed which would only change the variable in an easy to compute way (imagine, it'd only change a color, not the value of the list, or something similar)

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    The problem you mentioned is what I was meaning. There's no way to detect that except for comparing the fields old and new value. You'd need to make each field a separate state flow then to detect that

  • @carlosmspk

    @carlosmspk

    Жыл бұрын

    @@PhilippLackner Hah, I thought you meant that "combine" somehow solved that problem, and wasn't really understanding why. Thanks for clearing that up!

  • @mdisi5967
    @mdisi5967 Жыл бұрын

    Does live data have anything like this 🤔

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    Yes, there are some transformations, but i haven't used it in a while. It's not as much as flows offer, which is also not the job of live data though (it's a state holder and not a framework for reactive programming)

  • @Khaled_Ahmed_Elsayed
    @Khaled_Ahmed_Elsayed Жыл бұрын

    But this isn't related entirely to flows, you are just stating the single responsibility principal, and avoiding coupling 2 variables in 1 function, isn't it?

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    No, this is not really related to SRP 😅 The video is about using flows correctly to avoid bugs and race conditions

  • @tsmusic9587
    @tsmusic9587 Жыл бұрын

    u so handsome :*

  • @alicjamruk8446
    @alicjamruk8446 Жыл бұрын

    I really like your videos, they are very informative, but could you please be aware of using 'actually', it happens too often.

  • @PhilippLackner

    @PhilippLackner

    Жыл бұрын

    I know I'm actually already trying 😂

  • @fereshtemohamadi9237
    @fereshtemohamadi9237 Жыл бұрын

    Hi, Im fan of you from IRAN. People of IRAN need to theire voice heared. Please check the name #mahsa amini to figour out. Please be voice of iranians

  • @bofu9662
    @bofu9662 Жыл бұрын

    Thanks a lot!

  • @AmitJayant
    @AmitJayant Жыл бұрын

    In the combine example, isLoggedIn, chatMessages & users have default values. They will never change. How to make them get data from database?