RxJS made my code 5x shorter... but is it better?

  Рет қаралды 18,307

Joshua Morony

Joshua Morony

Күн бұрын

Пікірлер: 49
@JoshuaMorony
@JoshuaMorony Жыл бұрын
Join my mailing list for more exclusive content and access to the archive of my private tips of the week: mobirony.ck.page/4a331b9076
@panchcw
@panchcw 2 жыл бұрын
The way you compare declarative and imperative methods is amazing. please do this kind of videos more.really loved this
@pchasco
@pchasco 2 жыл бұрын
I’d be interested in a video where you write unit tests for this component. Our experience with RxJS is that it can make writing this type of code easier, but writing tests for it is difficult. For better or for worse, many organizations have a unit testing requirement for front end code. I’ve found that any modest gains in development time by implementing with RxJS can be nullified by the additional time it takes to write tests for it.
@JoshuaMorony
@JoshuaMorony 2 жыл бұрын
I've been thinking about making a video for this (I probably will) but I don't generally run into any hard problems with testing reactive code - do you have any examples (even if it's just a general description) of situations that have been challenging? I'll try to address that in the video.
@balintcsaszar6831
@balintcsaszar6831 Жыл бұрын
if you test the template of the component (I mean not calling component function, but expecting template values, element visibility...etc), then there should be no differences. If you would like to test only ts parts (I don't recommend it, because it is only half of the work), then yes testing rxjs can be trickier, perhaps you will need rxjs-marbles. Meanwhile for imperative code you need only fakeAsync+tick() or done(). At the end you should see (like from Joshua's example), using declarative approach is more maintainable, shorter and in unit test point of view, totally the same.
@SneakyRapt0r
@SneakyRapt0r Жыл бұрын
The reactive code seems a lot more readible at first glance, since it is way less to read. However, if you don't know much or anything at all about RxJS it is really hard to understand what the code does. I might have an unpopular opinion, but in a real world scenario I still would prefer the imperative version of the code. Especially when I'm new to a project, because it is easier to understand and work your way through the code base to get a graps of how everything is tight together.
@Ernestas23
@Ernestas23 Жыл бұрын
As someone who worked in some different teams, I have to agree 100%. Declarative code can look cool, but even in the Bonus example here it looks way too hard to read and understand, in my experience code like this causes way more issues. I think having a mix of both approaches is the sweet spot.
@v.bourdeix
@v.bourdeix 2 жыл бұрын
I've been using RxJs for years but I just discovered the iif operator through your video !
@richjoshuaalzate660
@richjoshuaalzate660 Жыл бұрын
Same here
@DavidSchmidt07
@DavidSchmidt07 2 жыл бұрын
I made a concerted effort a few years ago to be more reactive with my development and I'm super glad that I did!
@jonathangamble
@jonathangamble 2 жыл бұрын
I'd like to see more videos on Angular Universal... a specific topic would be rest api points... great content btw!
@pawekoaczynski4505
@pawekoaczynski4505 2 жыл бұрын
This is a great tutorial and you're the Angular & rxjs channel I've been looking for. Although I have a little bit of criticism. The photos on the right were very distracting (at least for me). I wish you used simpler images (like color background or numbers) and/or stopped animation when it wasn't needed (i.e. when you were explaining some other stuff). Other than that, I loved the video c:
@alextiger548
@alextiger548 2 жыл бұрын
The best as usual. thank you man!
@urchuk2006
@urchuk2006 2 жыл бұрын
Great job as always Joshua! Love rxjs videos so much. Keep going!!
@sergeipanasenko4923
@sergeipanasenko4923 10 ай бұрын
Such a nice declarative implementation! What do you think can this code be improved with signals?
@franciscogiordano298
@franciscogiordano298 2 жыл бұрын
This is great!!! Amazing work as always Joshua! My two cents: the only thing I would have done different is avoiding the iif inside the switchMap, and going for a simple if. I cant´t find a justification for using the iif there if you are not creating an observable. The normal if would be a lot easier to read IMO. Thanks for this content, it is a super valuable contribution.
@is-sam
@is-sam 2 жыл бұрын
I feel like this approach is more suitable for small to medium size applications that are not very complexe. I tend to work on really complexe web apps with a lot of business rules, and using this approach is just a pain in the ass
@CodingAbroad
@CodingAbroad 2 жыл бұрын
Love your videos I’ve certainly learned a lot. I’m making a new cms at my current company and been programming reactively everywhere and glad I did. I work with quite messy payloads from the backend. Do you always map your data from the service file level?
@JoshuaMorony
@JoshuaMorony 2 жыл бұрын
If I had data coming in a format that I needed to change yes I would pull that into a service, modify it to the format I need, and then have my components consume that.
@ImperiumLibertas
@ImperiumLibertas 2 жыл бұрын
Separate your services into two types, functional and transactional. The transactional services are responsible for receiving data from the backend and formatting it in a way that makes sense while functional services are responsible for specific functionality for a feature. That way many feature services can rely on one transactional API service. Each service maps it's data to specifically what it needs for it's purpose.
@DhainautRaphael
@DhainautRaphael 2 жыл бұрын
You did a great job with this video. The "refactoring" with RxJs was super interesting. Then you updated your code because features/requirements change = A good choice of "real world" type scenario. Good work ! In my opinion, RxJs handles the problem so differently that I'm not really a fan of the result. I can see the benefit of "exposing"/"managing" the observable, but stringing together a merge, map, switch, concatenation all in one block seems so hard to read and edit later. I'm not even talking about the unintuitive name of the RxJs operators... I will continue to follow you to see if I can finally better understand the benefits of RxJs within a project. For the moment, I remain on my opinion which is "too" complicated in relation to the benefits. I'll be really interested if you create your own RxJs "operator"/"method" to have a separate function with a very self-explanatory name.
@JoshuaMorony
@JoshuaMorony 2 жыл бұрын
Thanks for the comment! I think a big part of the problem with coding reactively with RxJS is that since it is such a paradigm shift it looks very intimidating and confusing until you spend quite a bit of time learning it. So you kind of need to be convinced the benefits are worth basically coding in an entirely different way and trusting that it's going to make sense at some point. And yes you can certainly make some optimisations to make things more readable, whether that is creating your own custom operator, or just splitting things out into more streams (e.g. as I did with playCurrentPhotos$ to make the role of that a bit clearer, maybe it would be even better to call it emitEachPhotoWithDelay$ to make it even more clear). And as I mention in the video, this stream is an atypical example that is more complex than most of the streams you generally have to work with. If it ends up being too much/you just don't like it, you can always just switch to using imperative code for specific components (especially if it is just your dumb/presentation components, it's not going to impact the overall reactive architecture of the application).
@DhainautRaphael
@DhainautRaphael 2 жыл бұрын
@@JoshuaMorony thanks a lot to have taking time to give a complete answer. I will continue to stay with an opened mind and look/ view your next videos ;) Maybe I will change my opinion about RxJs paragidm/library.
@elmalleable
@elmalleable 8 ай бұрын
​@@DhainautRaphaelafter a year. Any changes to share Raphael? Any experiments?
@alextiger548
@alextiger548 2 жыл бұрын
Joshua, do you have a code for the bonus example for html part of your template? Nice looking
@JoshuaMorony
@JoshuaMorony 2 жыл бұрын
Yep, you can find it on this branch: github.com/joshuamorony/ionicstart-snapaday/blob/insta-story-v2/src/app/slideshow/slideshow.component.ts
@mkez001
@mkez001 2 жыл бұрын
What do you think about @Input set methods? Although this is a method 'set' I always put this at the top around other @Input fields to clearly see what can get into the component :)
@JoshuaMorony
@JoshuaMorony 2 жыл бұрын
I try to keep with the default ESLint rules since I am often creating tutorials, so that's really the only reason I am placing the setter like this so that other people don't get ESLint errors if they try it out.
@only_one_chance
@only_one_chance 2 жыл бұрын
the delay$ stream doesn't look like a real pause actually :D Why don't just to do like switchMap((isPaused) => isPaused ? EMPTY : timer(1000))? Better behavior in my personal feeling. But anyway this is a good content you provide here. More rxjs stuff I'm waiting for, this is really cool especially mixing with angular !!!
@JoshuaMorony
@JoshuaMorony 2 жыл бұрын
I haven't actually tried it but I assume EMPTY won't work because it completes immediately, I did try NEVER which emits nothing and never completes, but it doesn't work in this case.
@only_one_chance
@only_one_chance 2 жыл бұрын
Yes but I think in case your pipe for concatMap is attached to internal one it doesn’t influence on the outside that emits photos I tried this with EMPTY and it works fine for me
@misha130
@misha130 2 жыл бұрын
Can't you set filter isPaused with another subject? Making it not emit anything while paused. Like this point seemed to me a little weird since it obviously only pauses for 10 seconds.
@vanilla_master
@vanilla_master 2 жыл бұрын
I'm not shure, but isn't imperative example of component just bad ? some generators and iterables, and it would be a great opponent rxjs one
@JoshuaMorony
@JoshuaMorony 2 жыл бұрын
Probably! That's why I posted this example to Twitter to try and see if the imperative example was a "fair" representation. It probably could be better, but I also think it's a pretty standard implementation (I don't think I've ever actually seen someone create their own generators/iterables in an Angular codebase). I am super curious to see what the result would look like though.
@vanilla_master
@vanilla_master 2 жыл бұрын
​@@JoshuaMorony after i did smal exampe, i realize, that i have no idea how to share link to it in YT comments, so here is a base64 encoded link: aHR0cHM6Ly9naXRodWIuY29tL1ZhbmlsbGFNYXN0ZXIvc25pcHBldHMvYmxvYi9tYWluL2dlbmVyYXRvci5qcw== if someone really become interested they can handle it ¯\_(ツ)_/¯
@JoshuaMorony
@JoshuaMorony 2 жыл бұрын
YT algorithm wasn't a fan of you posting a base64 encoded link and delete your comment lol, but I still got the notification for it! Here is vanilla's code for anyone interested: github.com/VanillaMaster/snippets/blob/main/generator.js thanks for sharing!
@dgcp354
@dgcp354 2 жыл бұрын
isn't xstate better for this kind of thing
@Iam_AndersonP
@Iam_AndersonP 2 жыл бұрын
Learning rxjs is harder yes, but in the long time (not so long) it is more benefit to the development cicle and also to the aplication performance, less manual subscriptions, and easy to implement state management
@kaibe5241
@kaibe5241 Жыл бұрын
It would be even shorter without the unnecessary parenthesis. Haha
@Ben-gq9tx
@Ben-gq9tx 2 жыл бұрын
why issit that most of the time the code shown in these kind of videos is completely pepega 🤦‍♂ switchMap(whatever => from(whatever) ? really?? maybe add a few more map(val => val) for more m4g1c? concatMap(whatever => of(whatever).pipe(delay....) ? like, why? just fucking do the dealy in the original pipe?
@aravindmuthu5748
@aravindmuthu5748 Жыл бұрын
Keeping in mind, all of the rxjs code shown here is framework agnostic. Almost all of the functionality can be copied and pasted into vanilla js and still works fine. Just wanted to throw this out for the people who think rxjs is Angular specific
@glitchinLife
@glitchinLife Жыл бұрын
RxJS is awesome, until you add routing to ur app 😅
@JoshuaMorony
@JoshuaMorony Жыл бұрын
What problem are you running into with routing?
@glitchinLife
@glitchinLife Жыл бұрын
@@JoshuaMorony I find trying to keep the app in sync with the queryParams very difficult to do, unless u subscribe to the activatedRoute or router-store (when using ngrx) manually, then sync the components, or maybe I just had some complicated use cases mixed with some bad luck and inexperience. E.g. Imagine a stream of markets (dropdown) each has a stream of products (list), and a stream of specialties or categories (tabs), on each tab I want to filter the products, the default tab is 0 (if not in the url), every time I change the market the tab should be 0, every market has different number of categories (2 or 3), each time I click on a tab the products are filtered, but the url shouldn't be changed unless I select a product from the new tab. I also want to be able to share the url to open app in the expected state with everything in sync, url, selected market, selected tab with the filtered products, and the selected product (if in the url). Errors should be handled obviously: when market doesn't exist in the dropdown, when tab doesn't exist (3rd tab may exist for some markets but not for others). I managed to do all that using streams and declarative approach, except initializing the app from url and changing the url from the app that I had to subscribe/unsubscribe
@TimothyBrake
@TimothyBrake 2 жыл бұрын
RxJs = 5% useful and 95% overcomplicates the most basic feature. Use RxJs for what it’s good at and don’t try to use a framework for the sake of using it.
@samchilvers3711
@samchilvers3711 Жыл бұрын
I find RxJs solves a lot of async problems that are inherent in imperative programming without any need to actually think about them. But that's just me :)
@TimothyBrake
@TimothyBrake Жыл бұрын
@@samchilvers3711 of course it does as that’s what RxJs is designed to do.
@_Greenflag_
@_Greenflag_ Жыл бұрын
I doubt this is the right approach / recommended approach : 1. According to the official doc, Observable are used for event handling, asynchronous programming, and handling multiple values. You don't don't create variable anymore, only streams of data. What is the impact on performances of this way of doing ? You should have a deep understanding of how Observable are created to do that / study the RxJS library in detail to see how it's working. 2. Only for displaying some photos, the code is fairly complex / barely readable. You violate the KISS (keep it simple, stupid ! :) ) principle. 3. I doubt this code is maintainable (you could easily add functionalities) and testable. 4. On the official Angular documentation, they do not use this way of writing code. Of course they use Observable, but not everywhere, for every variable. Thanks for a feedback if you know more about these points.
@JoshuaMorony
@JoshuaMorony Жыл бұрын
I responded to your other comment as well which already covered some of this points, but I'll fill in the gaps here: 1) If you want to code declaratively then you need something like a stream so you can react to changes. With the imperative approach, if something depends on some class member (that is not a stream/reactive), and that class member changes, then it is up to you to make sure you are manually/imperatively handling that change as opposed to it just happening automatically. Assuming that you aren't introducing some kind of bug/unintended behaviour there isn't really a performance concern here, these streams are really just functions behind the scenes 2) Obviously it requires knowing RxJS in the first place, and this is a subjective thing, but I disagree - I think the reactive code is simpler. With reactive/declarative code I can see what something is and how it behave in one place and it is generally shorter. With imperative code the behaviour is scattered around the component. I would say reactive/declarative code generally better adheres to the KISS principle (though I'm not really a fan of dogmatically following principles like that anyway) 3) Not sure what to say to this one - I've never had any trouble maintaining/testing my code. There are some specific situations with very advanced streams that can become a bit harder to test, but these are not the norm, and I generally find testing with streams to be a lot easier - (it is often in the form: do X, check that Y stream emits Z)
The secret to understanding piped operators in RxJS (Advanced)
9:06
How to deeply understand Angular signals (...or anything)
10:51
Joshua Morony
Рет қаралды 4,2 М.
Players push long pins through a cardboard box attempting to pop the balloon!
00:31
How Many Balloons To Make A Store Fly?
00:22
MrBeast
Рет қаралды 174 МЛН
Should we really NEVER subscribe in Angular apps?
13:22
Joshua Morony
Рет қаралды 18 М.
Why you actually need RxJS (even if you don't realise it)
6:53
Joshua Morony
Рет қаралды 21 М.
Angular change detection explained in 5 minutes
6:06
Simplified Courses
Рет қаралды 15 М.
How To Build Feature Flags Like A Senior Dev In 20 Minutes
20:33
Web Dev Simplified
Рет қаралды 101 М.
WTF is "Zone.js" and is it making your app slow?
13:21
Joshua Morony
Рет қаралды 55 М.
Why didn't the Angular team just use RxJS instead of Signals?
8:15
Joshua Morony
Рет қаралды 102 М.
Why I Cant Stand IDE's After Using VIM | Prime Reacts
17:51
ThePrimeTime
Рет қаралды 384 М.
Angular is about to get its most IMPORTANT change in a long time...
10:15
Why use OnPush in Angular? Not for performance...
13:16
Joshua Morony
Рет қаралды 32 М.
No Code App Development is a Trap
9:31
Coding with Dee
Рет қаралды 319 М.
Players push long pins through a cardboard box attempting to pop the balloon!
00:31