Technical Debt and Streams/BLoC (The Boring Flutter Development Show, Ep. 4)

Поделиться
HTML-код
  • Опубликовано: 8 сен 2024
  • In this episode, Filip and Matt start by erasing some of the technical debt that the Hacker News reader app accumulated in the past 3 episodes. They remove the new keyword everywhere, delete unused files, and re-enable unit tests.
    Then they set out to tackle state management and separation of concerns between view logic and business logic. They choose to follow the BLoC pattern, using Streams and ReactiveX (rxdart).
    With that in place, they implement a new feature: ability to switch between the listing of top and new stories.
    Let us know your thoughts and requests for future episodes in the comments below or on Twitter using #BoringShow.
    Watch more episodes of the boring show here → bit.ly/BoringShow
    Get started with Flutter → flutter.io
    Try a Flutter codelab → goo.gl/d3fHPo
    Join the conversation → goo.gl/68oUnb
    Subscribe to the Google Developers channel → goo.gl/mQyv5L

Комментарии • 138

  • @brennangambling8907
    @brennangambling8907 5 лет назад +126

    Streams/BLoC and State management starts at 18:45.

    • @RaedMughaus
      @RaedMughaus 5 лет назад +5

      I wish I have read the comments before 😭😭

    • @asif_mojtoba
      @asif_mojtoba 5 лет назад +9

      *not all superhero wear capes.*

    • @MuhdAimanRS
      @MuhdAimanRS 5 лет назад

      thanks bro

    • @YabbaDadADo
      @YabbaDadADo 5 лет назад +3

      People like you make the internet nice again :)

    • @anikhasan6729
      @anikhasan6729 4 года назад +1

      After 5 mins of watching the video, I had a feeling that someone might have commented this , I checked the comment section and found this. heheh thanks a lot

  • @redbrogdon
    @redbrogdon 6 лет назад +272

    Wait, you did one without me?

    • @vinceramcesoliveros6739
      @vinceramcesoliveros6739 6 лет назад

      Andrew Brogdon where were you when they needed you?

    • @semicognitive
      @semicognitive 6 лет назад

      João Gabriel Coutinho Dude that's kinda mean

    • @yodartt
      @yodartt 6 лет назад +1

      I guess you're right, my bad on that one :/

    • @RogerVargas0
      @RogerVargas0 6 лет назад +9

      Please come back with your dark IntelliJ

    • @brzhang109
      @brzhang109 6 лет назад

      haha ,you the boss

  • @user-fh4xo2pc2d
    @user-fh4xo2pc2d 5 лет назад +90

    We need an official guide for Bloc pattern.

  • @saraweber312
    @saraweber312 5 лет назад +33

    Watching the flutter devs struggle makes me feel a lot better about my own code 😅

  • @youkokaku
    @youkokaku 5 лет назад +3

    "This is all commented out code? Oh I love deleting code." Best comment ever, Filip!

  • @hadifromlebanon3812
    @hadifromlebanon3812 4 года назад +1

    That switch to vscode is visually relaxing

  • @mrbam8
    @mrbam8 4 года назад +2

    I give Google tons of credit for being brave enough to make these videos... can't be easy.. By the way, Thanks Apple!

  • @tushargupta6533
    @tushargupta6533 3 года назад

    This video saved my life 😭😭😭😭 I wasn't able to understand this thing but you guys explained it in a very very simple way🙏🏻 please continue this series

  • @benjaminli21
    @benjaminli21 2 года назад +1

    I know it's kind of too late now... but I think it might be better for adding the links of the package using in the episode in the video description.

  • @apf14378
    @apf14378 6 лет назад +2

    Suggestion for the next show:
    1.The list should not be updating completely each time you change stories type, each new item retrieved from the network should cause a bloc stream update with a new list containing just one more item and, if there is still more news waiting for retrieval, the list should also include "working" indicator as last item. I don't think anything else would be 'acceptable' for a serious app.
    2. You should go for inheritable widget, as it's what you are going to do in any other "non just playing" app.

  • @mokhosh
    @mokhosh 6 лет назад +2

    So glad you're back Philip :) Missing Andrew though, maybe you can do a three way (just flutter).

  • @NivenShah
    @NivenShah 5 лет назад +1

    Hi team - With BLoC pattern, what is the advantage behind strictly using sinks for inputs rather than void functions that do not return a result (ie, the result comes through a stream)? By using sinks for inputs, you need to create a sink, listen to the sink, and manage all the subscriptions internally instead of just calling out to a service. It seems like this (sink) approach requires more lines of code and more careful thought and attention from the developer to ensure s/he is managing all of it correctly. Thank you for these wonderful long-form videos by the way - what a great learning resource!

    • @filiphracek
      @filiphracek 5 лет назад +2

      Great question. The idea with Sink/Stream is, in my opinion, mainly important only if you're going all Rx / functional. At that point, it's easier to pipe things, and it's also conceptually easier to deal with the pattern when you know _everything_ is an asynchronous Sink or Stream. Additionally, asynchronous errors correctly propagate through the stream.
      That said, not everyone goes all Rx / functional (like, for example, the app we're building above). So it depends on how big of a purist you (and your team) want to be. I personally value simplicity over purity, so I wouldn't bat an eye if I saw someone using the adding a synchronous method to a bloc.
      We will be getting back to state management in the Boring Show shortly, trying to do just that: make it as simple as possible.

    • @NivenShah
      @NivenShah 5 лет назад

      @@filiphracek Thanks Filip!

  • @lucasnantes6484
    @lucasnantes6484 4 года назад

    It would be nice to hear more about BLoC Strengths and weakness and also an example of BLoC for configuration of In-App language

  • @abolfazlrezaei2801
    @abolfazlrezaei2801 3 года назад

    These guys are great

  • @JSANL
    @JSANL 6 лет назад +2

    Absolutly Love this show!

  • @fullemptiness
    @fullemptiness 5 лет назад +3

    I appreciate your work, but I'm hoping you make the non-boring show with the edit, less re-work and more preparing and focusing. This will help me in the few hours I only have in weekend.

  • @michelfeinstein
    @michelfeinstein 5 лет назад

    It's better to look for "Material Icons" on Google, than on the Flutter docs... It's in a grid, in the docs they are one per line, which makes the searching really tedious.

  • @Mohith7548
    @Mohith7548 6 лет назад +12

    #FlutterBoringDevelopmentShow () => Bloc pattern is not clear and is difficult to understand. Please make a detail concept-clear video on Bloc Pattern. Hey did anyone notice the white board?

    • @filiphracek
      @filiphracek 6 лет назад +15

      We always forget the white board :)
      Yeah, we hope to do a focused video on the Bloc pattern. But that might take some time, because distilling something like that into a video takes a lot of thinking.
      In the interim, here are some resources that might be useful (unless you already know about them, of course):
      - original I/O session: ruclips.net/video/RS36gBEp8OI/видео.html
      - companion article: medium.com/flutter-io/build-reactive-mobile-apps-in-flutter-companion-article-13950959e381
      - companion repo: github.com/filiph/state_experiments/
      - an article by Amrut Patil: codeburst.io/state-management-using-bloc-pattern-in-flutter-390d4056006f

    • @Mohith7548
      @Mohith7548 6 лет назад

      Thanks for the sources. I've been pushing hard myself to understand the Bloc pattern since this morning. I missed the codelabs.

    • @AndrewMooreReactle
      @AndrewMooreReactle 6 лет назад +3

      Instead of attributing amrut, you should really attribute Stephen grider and his udemy course which that article is a blatant copy of. I found the udemy course really helped my understand the bloc concept.

    • @ukaszhuculak7854
      @ukaszhuculak7854 6 лет назад +1

      I really like the show.
      I am particularly interested in the lifecycle of BLoCs. If the BLoC opens connections to external resources, it should also close them down. Is there any other way than to use InheritedWidget as a BLoC supplier for internal StreamBuilders (example: github.com/brianegan/flutter_architecture_samples/blob/master/example/bloc_flutter/lib/main.dart)?

    • @LukePighetti
      @LukePighetti 6 лет назад

      bloc pattern is very simple once you get used to it
      input functions/streams >> perform actions on data >> output streams
      That's Bloc in a nutshell. Everything else is idiomatic.

  • @kentonraiford7784
    @kentonraiford7784 5 лет назад

    Thanks for doing this! We need more tutorials on BloC and rxdart.

  • @PraveenAV
    @PraveenAV 6 лет назад

    Very very useful. Thanks friends.

  • @reilem
    @reilem 5 лет назад +2

    23:15 I was literally using StreamControllers and had this exact issue and was looking for a way to fix it. Thanks :D

  • @JeremyConnor
    @JeremyConnor 6 лет назад

    Great show, thanks team!

  • @Mohith7548
    @Mohith7548 6 лет назад +7

    I like the FlutterBoringShow. I want to throw light on the bug that makes me drink coffee (while the gradle builds). THe bug is, whenever you stop the app and run again, it always builds the previous version of the app. I have to manuallty do "flutter clean" in the terminal and run again. Then it takes a lot of time to build (as you know gradle is a timer lover). Please fix issue ASAP.
    #LoveFlutter

    • @filiphracek
      @filiphracek 6 лет назад

      Is this filed on github.com/flutter/flutter/issues? I _think_ I've seen this before, but can't reproduce.
      As a temporary workaround, does triggering a hot reload (or hot restart) work. In other words: stop app, start again, trigger hot reload (press 'r'/'R' in command line, or click the appropriate button in an IDE). If not, the next workaround would be to make a meaningless change (like temporarily adding a blank line somewhere), then saving.

    • @Mohith7548
      @Mohith7548 6 лет назад

      Filip Hráček Yeah! I'm saving time by do the same, making some meaningless changes and hot restart. But when I'm modifying code in state function (initState()) it doesn't make sense to do hot reload in that case. I need to delete the build folder and the build the app again. I don't understand why the problem has arrived, but it wasn't there in previous versions of flutter. Hoping that it will be fixed soon :)

    • @Mohith7548
      @Mohith7548 6 лет назад

      Here is the issue. It was already filed. github.com/flutter/flutter/issues/16604

    • @Mohith7548
      @Mohith7548 6 лет назад

      I'm on Beta channel. On which channel are you Phillip Sir?

    • @davidloera9202
      @davidloera9202 6 лет назад

      0

  • @argigentarna
    @argigentarna 5 лет назад

    Really nice Tutorial, i love the boring show. Hope the next tutorial build modify list view, llike button or something else.

  • @omidnejadabbasi2171
    @omidnejadabbasi2171 2 года назад

    Question: With this method the UI will wait untill all the items has ben fetched and that might take a logn time, how about a video that addresses that. and also how to animate items entering the list?

  • @truongsinhtran-nguyen7129
    @truongsinhtran-nguyen7129 5 лет назад +1

    6:12 www.git-tower.com for those who are also Interested in the tool for source version control the show hosts are using. I'm interested because I'm currently using SourceTree

  • @sreejithsreejayan441
    @sreejithsreejayan441 3 года назад

    What happens if we create the bloc many widgets(Like creating the bloc in home_page or something) down instead of passing through the constructor by constructor.

  • @darshangowda309
    @darshangowda309 6 лет назад +1

    Hey guys! so quick question, using a textfiled / textformfield inside a stream builder refreshes the entire builder widget. How do I use something like a form inside a stream builder with data pre populated ? Is there a work around ?

    • @sanathnherath
      @sanathnherath 5 лет назад

      same thing happen to me but no solution yet, did you find solution

  • @harshadmanglani1309
    @harshadmanglani1309 4 года назад

    If we use streams, and let's say the API updates the IDs to put like another story on the top, will my app change in real time? I'm a bit confused with streams.
    Basically, I'm trying to ask if streams make periodic calls to the API to monitor changes on their own and update if necessary (much like an Instant Messaging App)

  • @raycharlz4937
    @raycharlz4937 3 года назад

    I did the same code but the line "key: Key(article.text)" in _buildItem Widget caused a duplicate key error that doesn't appear in the show... why?

  • @ramaagusdwiputra1960
    @ramaagusdwiputra1960 3 года назад

    State management starts at 18:48

  • @mohabmagdyshokryabdel-hame3203
    @mohabmagdyshokryabdel-hame3203 5 лет назад

    Filip, please share with us your live templates they are great and save me much time I just need to copy them and paste them on my IDE and thanks guys for this great unBoring show =)

    • @bacharsaleh6984
      @bacharsaleh6984 5 лет назад

      add these to live templates
      Stream get $OBJECT_NAME$ => _$OBJECT_NAME$Subject.stream;
      final _$OBJECT_NAME$Subject = BehaviorSubject;

  • @Alex-fs6kz
    @Alex-fs6kz 5 лет назад

    Is there a public repo available with this code? I would like to review what you created in this episode because scrubbing the video is a bit difficult.

  • @pashute12
    @pashute12 5 лет назад

    Nice. A small remark: Glaring issues are pronounced GLERRing issues

  • @hiaw
    @hiaw 6 лет назад

    Did you figure out how to run the skipped test? Quick search didn't get anything for me.

  • @moveaxebx
    @moveaxebx 5 лет назад

    Why mixing dart streams with rx observables in the bloc? StreamController vs. BehaviourSubject...

  • @randlemcmurphy6293
    @randlemcmurphy6293 5 лет назад

    In clean architecture, which layer do blocs belong to? Domain layer? Or presentation layer?

    • @remmievail8148
      @remmievail8148 5 лет назад +1

      From what I understand, blocs provide data, execute business logic, but not actual logic for how data is displayed. From that standpoint, I would not include them in the presentation layer.

  • @muhammadchhota4463
    @muhammadchhota4463 6 лет назад

    What is use of immutable object? In the news application it's making sense that once news articles is created then it won't change.but in some applications we need to change the state of object. Example shopping cart or notes app. How to use immutable object in those cases?

    • @andrewbrogdon558
      @andrewbrogdon558 6 лет назад +2

      One of the big advantages of immutable objects is that you know they can't change without your code knowing it. If you have a mutable object referenced in two places in your code, for example, one of them could change it without the other getting notified or being aware, so to speak. With immutables, once you receive an object, you can code knowing that it won't change, and you won't need to update the UI until you receive a new object from whatever source is generating them (a stream, for example).
      As far as making changes goes, while you can't modify an object, you *can* create a new object that's a modified copy of the old one. The built_value package uses methods called "rebuild" for this: medium.com/dartlang/darts-built-value-for-immutable-object-models-83e2497922d4#5f61

  • @seanbruceful
    @seanbruceful 6 лет назад

    very fun and cool show. I am a newbie flutter developer and I'm very glad to see more and more flutter stuffs in google develepers channel. I also have a question about this episode which is Can I and should I use built_collection to replace unmodifiableListView, what's the adventage and disadventage of them?

    • @filiphracek
      @filiphracek 6 лет назад

      Good question! You can definitely use built_collection (such as BuiltList, in this case) instead of UnmodifiableListView.
      The advantage of BuiltList is that it guarantees some things that UnmodifiableListView doesn't. For example, by default, Built objects cannot be null. Also, they're immutable all the way down (while an UnmodifiableListView could contain in it objects that you can modify, and UnmodifiableListView can't prevent you from doing that). Another advantage is that serialization is easy to add, which might be something you care for.
      The disadvantage is that it's (generally) more code. UnmodifiableListView is just that one wrap around your list and that's it.

    • @seanbruceful
      @seanbruceful 6 лет назад

      😄Thank you Filip

  • @greywolf1632
    @greywolf1632 5 лет назад

    Hey Matt, could you please share what color theme you're using in VSCode at 46:19 ? It looks nice.

  • @MuhammadFahreza
    @MuhammadFahreza 6 лет назад

    What is the purpose of Unmodifiable List View ? Why we could not use ListView instead ?

    • @murkyglasses
      @murkyglasses 6 лет назад

      As I understand it, you don't want others (including other class or view) to update your list data (outside the bloc). So you convert it to unmodifiable list.
      I think this is a good practice, as your views will only consume data and any modification should be done on bloc. Will definitely keep this in mind when I revamp my flutter project.

  • @murkyglasses
    @murkyglasses 6 лет назад +1

    When using bloc pattern and firebase, is it advisable to move the stream firebase call to bloc also? and if so how would you do it?

    • @filiphracek
      @filiphracek 6 лет назад +4

      I would advise it, yes. I don't think your view logic should care about the implementation details of Firebase connections, references, etc.
      There are many ways to do this, and none of them is - in itself - better than others. The simplest is to encapsulate the Firebase code in the bloc. Initiate the connection with Firebase/Firestore in the constructor of the Bloc (and, if your bloc has shorter lifecycle than your app, don't forget to close it in a close() method). Then translate the inputs to the Bloc to Firebase calls (if needed), and firebase callbacks to bloc outputs (again, only if needed).
      A more robust (and testable) approach would be to inject the firebase service to the bloc. So our main method would look something like:
      void main() {
      final dbService = MyFirebaseService();
      final myBloc = MyBloc(dbService);
      runApp(MyApp(myBloc));
      }

    • @murkyglasses
      @murkyglasses 6 лет назад +1

      Thanks for the advise, I'm starting to move my Firestore calls to bloc and just started using built value. I'm just a bit confused about closing bloc/firestore? do you know any articles I can refer to about it? I assumed it will automatically be garbage collected after widget is gone?

  • @unityme8898
    @unityme8898 6 лет назад

    hello guys, can you help me on this ??? ----> How do we use the single global instance of Bloc to such a way that, the submit button will only enable for user to click when both email and password stream contains no error?

  • @poluxsaurus1454
    @poluxsaurus1454 5 лет назад +1

    Bloc pattern gets considerably friendlier with a library like github.com/felangel/bloc

  • @RichardVowles
    @RichardVowles 6 лет назад +1

    Why do you keep exiting IDEA to commit? Why not just type Command-K and go from there?

  • @nihaddelic5032
    @nihaddelic5032 5 лет назад

    How to get t-shirts, sticker for flutter and dart? Or bird toy?

  • @johnchen4486
    @johnchen4486 6 лет назад

    where is the source code of the example?

  • @sanathnherath
    @sanathnherath 5 лет назад

    I am developing user profile update page for a app, I got problem there, To populate form with initial data I have used StreamBuilder and used TextEditingController load data to TextField, data loading fine and works well, but problem is when I try to change TextField and focus to next TextField StreamBuilder refresh the ui with tha data which load previously and lost edited data. In this case Stream does not updated from network call. Anybody came across this situation ? or any recommended way to do this?. Please help.

  • @amanihamila6305
    @amanihamila6305 6 лет назад +1

    Anyone has an idea about how to use BloC pattern in angular Dart ? i'm trying to implement code sharing, so i gotta understand that first to be able to use my blocs/common code in angular dart.

    • @Mzulfreaky
      @Mzulfreaky 6 лет назад

      Amani Hamila ahh i have beem thinking about code sharing too! Please tell me if you find a way on it! Thanks in advance

  • @athosdomotics7104
    @athosdomotics7104 3 года назад

    Hello there,
    Thanks for the videos,
    Where can I get your Flutter T-shirt ?
    Regards

  • @shamscorner
    @shamscorner 3 года назад

    12:25 And that's how Windows developers deal with technical debt. 😆😄

  • @user-fj6mo3ft5k
    @user-fj6mo3ft5k 5 лет назад

    Any one know ? where could I clone the demo code of the BoringShow?

  • @digitart-media
    @digitart-media 6 лет назад +1

  • @DakshGargas
    @DakshGargas 6 лет назад

    Why didn't you use `StreamController` instead of `Sink`?

    • @brzhang109
      @brzhang109 6 лет назад

      because ,they are the same.. StreamController use sink add event...

  • @UCjNrKLyRJI-abFA8qiNo92Q
    @UCjNrKLyRJI-abFA8qiNo92Q 6 лет назад

    Talk about Google Maps, what have you done?

  • @ride4sun
    @ride4sun 5 лет назад

    I am wondering how you get the code completion for the Stream. Do you have templates loaded for that?

    • @bacharsaleh6984
      @bacharsaleh6984 5 лет назад

      add these to live templates
      Stream get $OBJECT_NAME$ => _$OBJECT_NAME$Subject.stream;
      final _$OBJECT_NAME$Subject = BehaviorSubject;

  • @satishkumar-qq8df
    @satishkumar-qq8df 5 лет назад

    Our team has created a paint application, we are storing to JSON file. actually what happening after drawing 15 to 20 minutes drawing gets slow.
    Can you suggest me some best way that we could build better app.

    • @nothappyz
      @nothappyz 5 лет назад +2

      Are you seriously using jsons to store a picture?...

  • @ShubhamSoni-wo9by
    @ShubhamSoni-wo9by 6 лет назад

    The main problem i found with bloc pattern and Stream builder is that When you have bunch of pages in the app and the view of the page depends upon the stream of data coming in according to the sink of input object. If there is any network call between sink of input and stream of output then the page will show the old data that was on the stream untill it get a new data. And we know internet connection can be very pathetic.
    Is there any way to show some CircularProgressIndicator untill the stream data is updated.

    • @glitch3dout
      @glitch3dout 5 лет назад +1

      The way I solved this is by emptying the stream by pushing in an empty list before doing the network call, and then after the call is successful, I update the stream with the data. Meanwhile in the UI, whenever the stream is empty, the CircularProgressIndicator is displayed, and when it has data, the data is displayed.

  • @biezhi
    @biezhi 6 лет назад

    Thank you share 🍭🍭

  • @ShubhamSoni-wo9by
    @ShubhamSoni-wo9by 6 лет назад

    Another problem with builders is that we can't merge streams in it. I tried StreamGroup.merge and I also tried with Observables. By using Observation1.mergewith([observable2]).
    In both the cases the data shown by the view is of only single Stream or observable .
    I tried lazy streams too it also didnt work please show a way to merge 2 streams and use a one stream in the stream builder.

    • @remmievail8148
      @remmievail8148 5 лет назад

      Your bloc should perform the work of merging two steams into one, so the builder only has to consume 1 stream.

  • @rubensdemelo
    @rubensdemelo 5 лет назад

    20:43 create bloc class

  • @lintonachmad6410
    @lintonachmad6410 6 лет назад +1

    Add Google Maps 🗣🗣

  • @sunilk9760
    @sunilk9760 3 года назад

    they are using rxdart instead of StreamController
    funny

  • @JacobPhillips
    @JacobPhillips 6 лет назад

    Is there a repo link?

    • @filiphracek
      @filiphracek 6 лет назад +1

      Sure: github.com/filiph/hn_app

    • @marconapoli1212
      @marconapoli1212 6 лет назад

      The github repo is at github.com/filiph/hn_app

  • @Dorumin
    @Dorumin 5 лет назад

    Have you been writing rust code?

  • @jpkontreras
    @jpkontreras 5 лет назад

    i need the font name!!!!

  • @Davo2able
    @Davo2able 6 лет назад

    Can you guys use a dark theme? The current theme is hard to look at in low light situations.

  • @jibraniqbal7830
    @jibraniqbal7830 5 лет назад

    this shows how much mess coding can be even though, you are google developer, kodus to all the developer out their, specifically mobile ones.

  • @yaswanthamaraneni7529
    @yaswanthamaraneni7529 5 лет назад

    Isn't it cool, if visual studio code can give suggestions to add dependencies in pubspec.yml file?
    for example, at ruclips.net/video/fahC3ky_zW0/видео.html, behaviourSubject needs rxdart dependency to be added in pubspec.yml, so if VS code can show dropdown suggestions there will be nice a feature.

  • @FernandoRosentalski
    @FernandoRosentalski 5 лет назад

    hey devin, play us a song

  • @triandisunarya8841
    @triandisunarya8841 6 лет назад

    flutter demo crash a lot in my lolipop smartphone when i try to check it out

    • @filiphracek
      @filiphracek 6 лет назад

      That is definitely a concern. Could you please file an issue at github.com/flutter/flutter ?

  • @Mohith7548
    @Mohith7548 6 лет назад +4

    I have to make playback speed as 1.5x ;)

    • @filiphracek
      @filiphracek 6 лет назад +1

      That's the best (least painful) way to watch this show. We should probably mention that in the video. The option to speed up YT videos is not that well known.

    • @franckadonis2623
      @franckadonis2623 6 лет назад

      2X man

  • @furkanvatandas4819
    @furkanvatandas4819 6 лет назад

    This topic is really confused

  • @csfolks
    @csfolks 4 года назад

    Hi, I am trying to reproduce this but I am having issues as snapshot is always staying in the Connectionstate.waiting. Could anyone please help me debug this. More information here: stackoverflow.com/questions/62143711/streambuilder-snapshot-is-not-getting-out-of-waiting-state-while-using-bloc

  • @jennabourgeois7985
    @jennabourgeois7985 4 года назад

    Might be one of the worst technical video productions. Try listening to the video without looking at the screen and you will see what I mean. There is absolutely no narrative explaining what you are trying to accomplish...

  • @hackerunet
    @hackerunet 5 лет назад

    Too boorinnggggggg!!!