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

Поділитися
Вставка
  • Опубліковано 20 гру 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.

  • @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!

  • @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.

  • @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: ua-cam.com/video/-CoVmNvp_1g/v-deo.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

  • @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.

  • @CraigShearer
    @CraigShearer 2 роки тому

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

  • @johnbauer9907
    @johnbauer9907 2 роки тому

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

  • @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.

  • @Aprofox
    @Aprofox 2 роки тому

    Im glad i found your chanel :) thank you for great 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.

  • @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.

  • @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.

  • @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?

  • @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. 🤙

  • @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 ;)

  • @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!

  • @ricardomartinez1308
    @ricardomartinez1308 Рік тому

    I love your content!

  • @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

  • @adrianosotos9433
    @adrianosotos9433 2 роки тому

    Niceee!! Thanks for the content

  • @radvilardian740
    @radvilardian740 2 роки тому

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

  • @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

  • @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.

  • @annantsharma91
    @annantsharma91 2 роки тому

    Love your content

  • @carameloweb
    @carameloweb 2 роки тому

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

  • @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

  • @glimpsee7941
    @glimpsee7941 Рік тому

    1:49 Kaysh - cache = cash.

  • @jayakumar2927
    @jayakumar2927 2 роки тому +1

    Share github url