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 Жыл бұрын
The way you compare declarative and imperative methods is amazing. please do this kind of videos more.really loved this
@pchasco Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
I've been using RxJs for years but I just discovered the iif operator through your video !
@richjoshuaalzate660 Жыл бұрын
Same here
@DavidSchmidt07 Жыл бұрын
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 Жыл бұрын
I'd like to see more videos on Angular Universal... a specific topic would be rest api points... great content btw!
@urchuk2006 Жыл бұрын
Great job as always Joshua! Love rxjs videos so much. Keep going!!
@DhainautRaphael Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
@@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.
@elmalleable4 ай бұрын
@@DhainautRaphaelafter a year. Any changes to share Raphael? Any experiments?
@pawekoaczynski4505 Жыл бұрын
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:
@is-sam Жыл бұрын
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
@alextiger548 Жыл бұрын
The best as usual. thank you man!
@sergeipanasenko49237 ай бұрын
Such a nice declarative implementation! What do you think can this code be improved with signals?
@franciscogiordano298 Жыл бұрын
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.
@CodingAbroad Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
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.
@only_one_chance Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
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.
@mkez001 Жыл бұрын
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 Жыл бұрын
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.
@alextiger548 Жыл бұрын
Joshua, do you have a code for the bonus example for html part of your template? Nice looking
@JoshuaMorony Жыл бұрын
Yep, you can find it on this branch: github.com/joshuamorony/ionicstart-snapaday/blob/insta-story-v2/src/app/slideshow/slideshow.component.ts
@Iam_AndersonP Жыл бұрын
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
@vanilla_master Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
@@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 Жыл бұрын
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 Жыл бұрын
isn't xstate better for this kind of thing
@TimothyBrake Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
@@samchilvers3711 of course it does as that’s what RxJs is designed to do.
@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
@kaibe5241 Жыл бұрын
It would be even shorter without the unnecessary parenthesis. Haha
@glitchinLife Жыл бұрын
RxJS is awesome, until you add routing to ur app 😅
@JoshuaMorony Жыл бұрын
What problem are you running into with routing?
@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
@_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 Жыл бұрын
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)
@Ben-gq9tx Жыл бұрын
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?