What I learned from this crazy RxJS stream in my Angular app

Поделиться
HTML-код
  • Опубликовано: 11 дек 2024

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

  • @ChauTran
    @ChauTran 2 года назад +43

    About "Using concat", you can put "startWith()" at the end, after "distinctUntilChanged()" and the startWith would behave as you would expect, aka it would not go through the debounceTime

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

      Oh nice, I'll give that a go - thanks!

  • @omergronich778
    @omergronich778 2 года назад +12

    Love this type of content. Going in-depth on all these cool rxjs operators is a lot of fun.
    Thanks :)

  • @Neutralpointz
    @Neutralpointz 2 года назад +2

    This was really an eye-opener for me. I knew a thing or two about how to handle data with rxjs but there's so much to learn. It is amazing. Thanks a lot!
    I hope I can see more rxjs content.

  • @joeyvico
    @joeyvico 4 месяца назад

    These tutorials are genius. Thanks Josh!

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

    RxJS is such a headache to wrap my head around 😂😂
    Especially because of a lack of real world examples.
    So, thank you for this.

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

    I recently realized I need to deepen my understanding with Rxjs and your videos have been gold. Thank you for serving these cases with proper examples, keep it up!

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

    Another great video - I've not used scan or expand (or reduce) either. Good to get a clear explanation of them.

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

    That was an excellent explanation of the span operator. I use it in my apps for CRUD operations but I was struggling to explain how it was working as elegantly as you did.

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

    I'm only just studying programming, but when I hear that rxjs has more than 100 operators, it makes me more excited to learn about all of them than nervous.

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

    Wow. That was such a good video. Very good explanation.

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

    Im glad i found your chanel :) thank you for great content

  • @ricardomartinez1308
    @ricardomartinez1308 Год назад

    I love your content!

  • @shemmuthanga6352
    @shemmuthanga6352 2 года назад +7

    🤯 Hard to imagine how difficult it would be to do the same without rxjs! Scan is such a cool operator.
    Suggestion: We could set a default value when initialising the formControl, e.g new FormControl('gifs'), then instead of having of('gifs'), we can have, of(subredditFormControl.value). This way, the user can know what word was searched for the first results displayed.
    Keep up the great content, Josh 👍🏾.

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

      That's a great suggestion, I'll combine that with Chau's suggestion regarding the concat!

  • @anj000
    @anj000 Год назад +1

    9:17 looks weird.
    So we are using "gifs" as the starting point, but the form input does not show that.
    And you were right couple minutes earlier. It indeed looks like madness. I wonder if this added complexity has any advantage?
    Amount of nested code looks like something that a person fresh from collage would wrote as the first program.
    What would be advantage of using this approach over something like Vue or Svelte?
    Even simple operations like getting a parameter into a reactive variable look complex.
    RxJs
    const my_value$ = some_value$.pipe(map(s => s.variable), distincUntilChanged())
    Vue
    const my_value = computed(() => some_value.variable)
    Svelte
    $: my_value = some_value.variable

    • @JoshuaMorony
      @JoshuaMorony  Год назад

      This video is probably the most succinct explanation I can offer that describes the why of RxJS: ruclips.net/video/-CoVmNvp_1g/видео.html - in short, if you want to be reactive/declarative and you also want to handle async reactivity then you are going to need RxJS or something that does the same things as RxJS. Svelte, Solid etc. don't handle asynchronous reactivity by default

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

    Niceee!! Thanks for the content

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

    Hey Josh, great video! Would you mind to do a video of how to unit test this kind of stream?

    • @JoshuaMorony
      @JoshuaMorony  2 года назад +2

      I built this app with TDD so I do just have the tests sitting there, so I might do a vid on it! Although I was thinking of doing a more broad testing vid. In general though I test this just like everything else - I take a black box approach so it's not like I'm testing individual operators, I just subscribe to the resulting stream in my tests and assert what should happen under certain conditions. For example, in one of my tests I mock some settings that require 15 gifs per page, and I will provide a mock http response that only provides 4. Then in my test I will expect that the gifs stream still gives me 15 gifs. So my tests don't care how something is being done (e.g. that the expand operator is being used) they only care about the result.

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

    Love your content

  • @beluv
    @beluv 2 года назад +2

    Great video! It was great to get an introduction to expand and scan.
    EDIT: What I said below is wrong. Sorry for the misinformation!
    Something to note: combineLatest will be removed in RxJS v8. I've been slowly replacing it with combineLatestWith to prepare.

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

      combineLatest the operator is being removed. combineLatest the function isn’t

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

      @@ChauTran Thanks for the correction! I saw something about it in the docs but must not have notice what page I was on.

  • @GlennImson
    @GlennImson Год назад

    Hi Joshua - I learned a lot on this video. Hopefully you can give to us it's repository link so I can debug it step by step. There's a part I'm still confuse.

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

    Questions: does the use of RxJS really necessary for this specific problem? Does it overcomplicate the solution? Is it harder if it was implemented non reactively? What can you when doing this complex RxJS within a team, is it sustainable?
    Sorry for a lot of questions. Great content. 🤩

    • @JoshuaMorony
      @JoshuaMorony  2 года назад +2

      Maybe I'll do a video comparing this stream to a non-RxJS version of the same thing. Your questions are too big to give good answers to here, but I'll give some brief thoughts.
      Is it necessary? No, there are many ways you could do this and people have built things without RxJS for a long time (and still do).
      Does it overcomplicate? I think it simplifies - with this approach I can do more, in a safer way, with less code. But, if you don't have strong RxJS knowledge then you might consider it complicated.
      Is it harder to implement non reactively? That depends - again, someone without strong RxJS knowledge would probably have an easier time building this in a different way.
      Is it sustainable? It is if your team knows RxJS - I would say most frameworks or libraries won't work well in a team environment if the people on the team don't know how to use them.

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

      @@JoshuaMorony thanks for your response. Make sense. So RxJS is just like a programming style, an options for devs to do functional programming.
      Looking forward to that comparison video. It's good to have comparison so that newbies (like me) can appreciate the power of RxJS.
      Thanks. 🤙

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

    consider wrapping the extend on a defer operator to make it a cold observable with an internal state so you can keep the variable gifsRequested on the body of the defer operator and so you don't need to pass it through the fetchFromRedit function

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

      Thank you for the suggestion! I'll look into this

  • @manar.kurmanov
    @manar.kurmanov Год назад

    Hi Joshua, thanks for a such a great real world example.
    I have only one question here:
    Does this stream even stop? For example if there is no GIFs left?

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

    I have a question, why do you nest pipes inside your operators? I thought you could just chain operators inside the one pipe and in the end just subscribe or use the async pipe

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

    Quick question, why're u using triple map operator there, while u can just use one to combine those values ?

  • @rishukumar7586
    @rishukumar7586 Год назад

    although the explanation was good ..but request you to use streams diagrams which will change game all together while explaining rxjs operators functionality

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

    github of this code? i would like to see the whole code... tks!!!

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

    Hi Josh! Great explanation and display of all the different operators used here. One question though, did you think about the case that the recursive part could produce more gifs than requested in the page size? Since this is an infinite scroll it could probably be ignored, but if it was a page with an exact size it would look a bit strange having, for example, 33/30 results.

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

      I'd have to get my head back in this code again to be sure, but I'm pretty sure I set it up so that the `gifsRequired` being passed in will accurately reflect how many should be fetched, e.g. if we have 27/30 on the next run the gifsRequired will be 3 and it will only fetch that many

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

      As per my understanding you get 100 posts from the API and take only the gifs from those posts, which lets say would be 20. Then you have 20/30 and you'll get another 100 posts where you end up with 15 gifs. So you have 35/30.
      Now I've missed the bit where you use gifs.slice(0, settings.perPage) in a map to never return more than the requested number of gifs. So my question is actually answered, sorry :)
      Although now it's necessary to consider the correct place to assign the after value in the paging. If you'd use the last gif from the last API call (number 35) you would miss 5 gifs from the thread on the next page. But I think you probably using the last gif after slicing, so thats fine. Would then just be a very slight efficiency optimization to cache the 5 gifs that were thrown away before, to not load them twice. But thats probably not important here ;)

  • @glimpsee7941
    @glimpsee7941 Год назад

    1:49 Kaysh - cache = cash.

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

    Hey Josh, does it matter what observable stream you are piping when you concat another stream?

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

      Nope, whatever streams you give it concat will just wait for the first stream to complete (emitting all its values) and then it will subscribe to the next stream you gave it (emit all those values), and then the next stream and so on. If you just want emissions from any of the streams whenever they emit (rather than being ordered like with concat) then you might want to use something like merge instead.

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

    Share github url