I appreciate a lot this explanation. Finding variables through the code is always a mess for me. But I dont understand the last code example. The buyItem method is empty and said that is managed by observable... But how? Can someone give me some hint? Thanks
Been a while since I looked at this code but yeah that code sample leaves a little too much to the imagination (especially since the method isn't even bound to clicking the button). Anyway the general idea here is that when the button is clicked it triggers some process in the itemsService (maybe we next some subject when the buy item is clicked like: itemsService.purchase$.next(itemId)). Within the itemsService, whatever needs to happen as a reaction to that happens, and ultimately the "itemsInStock$" observable would emit a new value as a result
Observables and RxJS operators are a game changer. That being said, RxJS is also a powerful foot-gun and it is easy to get yourself into a situation where your declarative pipes are every bit as convoluted and even harder to debug than straightforward imperative code. This is especially true when combining observables.
I find observables harder to debug almost every single time, because the stack trace is very muddy (by definition), the whole point of the observables is decoupling the "catalyst" from the "results". This breakage makes it very hard to look at a result and determine its catalyst. In our app, we've had many components that started out imperative and then were rewritten declaratively to handle some race conditions, only to be simplified back down into imperative code again when they became too complex to debug.
@@BenjaminLeeds that sounds like your approach was flawed. Rxjs is a dream for handling race conditions. It really shines when you make each observable as small as possible and embrace the single responsibility principal. Eventually rxjs code starts to read like english! If your observables are setup correctly their dependencies should be clear and almost similar to a pure component where it only relies on the inputs and outputs with no side effects.
@@ImperiumLibertas If I could sum up my experience with Angular and with RxJs inside of Angular it would be this: "I wish I was smarter so I could write good Angular code, but I'm not smarter, so I wish I wasn't writing Angular." My approach was probably flawed. I prefer solutions that don't encourage flawed approaches, because probably if I'm doing it poorly, my teammates are as well.
I think the key reason you should work declaratively as much as possible is that your main goal with any component should be to minimize state as much as possible. That means as few writable or mutable public properties as humanly possible within your component. This holds true for any component based web framework.
You are so great at explaining challenging topics and have really improved your presentation style. When I first saw your videos I was a bit overwhelmed by your focus on ionic, but even then you still had really good Angular content. I see you've recently done a lot more Angular and the quality of your videos is even better now so really excited to see more videos from you. I think you will reach 1 million subscribers. You are special.
It’s a great idea to confine the logic of how a value gets calculated to a single spot, even if you’re not using declarative/functional patterns explicitly. I use Lightning Web Components at work, a different frontend framework that lacks RXjs’ rich declarative library. For every bit of state that gets exposed from my components, I have a single “setThisValue” function that reads all the surrounding state it needs to calculate and set that value. I think imperatively call that “setThisValue” function any time that value might need a refresh
Recently, I'm just get into learning how to code reactively and I found your videos super useful. Thank you for all your videos and hope that there will be more about this topic
As someone who also uses more the declarative approach, I like the video. One suggestion though, when using a ternary operator, you don't need " ? true : false" since the left side of the ? operator (condition) already returns a boolean, right? That's the point of a ternary operator. So we can just use and return that value. In this case at 6:10 it would be: map(itemsLeftInStock => itemsLeftInStock > 0) I always get triggered by this, when seeing it in the PRs, since it's redundant.
I found this video incredibly useful. 6 months after switching to Angular from React I am not declarative 100% but I end up always subscribe to observablels as a part of my brain still tells me that I need to "own" those state values by storing them in variables. The example you are showing here is a lot smoother and shows me I still have along way to go and adjust to this mindset. I would like to become a pro member on your platform but for the moment I am not interested in Ionic but purely on Angular. I was wondering if you have more courses going to be added on that..! Not judging, I think that what you are doing is great is just that I am not into mobile apps rn
I am planning to do an "Angular only" flavour of Ionic Start soon, but Ionic Start already is mostly just an Angular course where you are using Ionic UI components instead of something like Material Design components
It's sort of interesting to me reading that you switched from React to Angular. These days I normally hear the opposite. I'm glad about that, since I've always preferred Angular over React.
@@WolfElectronicS well I ended up leading a team which is experienced in Angular and forcing them to switch to React would've taken too long... However I ended up enjoying the built in tools Angular comes with but there are some things like forms which ended up being way too complicated for what it needs to do really. Also having a route-aware menu in React is as simple as using a hook while in Angular you might end up subscribing to the router events, finding the Navigation end... I mean this is way more verbose than it should be and IMO Angular has some work to do in smoothing some rough edges but so far it has proven to be more reliable than Next JS which would randomly require me to edit bits and pieces of the framework I don't feel I should've touched
@@WolfElectronicS React js is a blasphemy for JavaScript community. React nonsense must be banned across world plane. This f library makes web development unnecessarily complicated. Angular is far better than svelte and react nonsense., because it leverages rxjs subscription, angular service make communication between sibling components much easier, developers know what exactly is happening. Svelte and react have confusing code. Developer experience matters.
So, I'm currently focusing on wrapping my head around wave function collapse and am almost there. That's how I found your channel this morning. Got this vid in my recommended figured I'd give it a shot. Been procrastinating on learning more of Angular and a lot of tutorials for it don't leave me feeling like I really understand what I'm doing or what's happening. But this gave me a whole lot in 9 minutes- it gave me some why's and how's for best practices, and doesn't overload with every bit of information to know at once. But just as importantly, it made me aware of weaknesses- the only thing I still don't follow understand is promises and obversables. But, I'm left with those two alone, and not 500 other things I'm super stressed about learning. One step at a time though, got a concrete thing to work on now.
This is a really cool comment to read, thank you - and I like that you found the channel through one of the few non-Angular videos I've published recently. As for promises and observables, I also have a recent video that might help provide some context: ua-cam.com/video/vdsujUhFMLY/v-deo.html
Speaking as a newbie to Angular, I personally lack some background knowledge to understand the concepts. Most of the background knowledge is around RxJS & other Angular concepts. Might link another video you have that covers those topics for people starting out. Really fascinating video, exposed me to a number of topics, so cheers!
Fantastic explanation I've just started using Angular and RxJS and I knew right from the start that I was missing something. This coding style looks unnatural at first, but now I'm starting to understand it's benefits.
I have been down this road myself. One thing I would like to add is that part of the power of this library comes in the form of functional programing. Although the Observer pattern is more flashy because makes it "reactive" it is only one part of the equation the other is in reality functional programming with all the great things it has like pure functions and thus avoiding side effects and of curse like you mention a few times :) makes the code declarative rather than imperative. The declarative part comes from functinal programming and not from Observer pattern.
This is a really great video and I'm going to show it to our other devs. I'm also glad that because it's informative and practical, the comment section isn't going to devolve into ribbing you like the last several more...experimental...videos.
Would be interesting to see your view on the corresponding ItemsService implementation, like receiving list of items from server, adding/removing some, sorting etc.
Most of my videos use this approach, so there should already a bunch of uses cases for you to look through if you want (even if the video isn't specifically about using the declarative approach) and of course my future videos will also be using this approach too
I think for me the distinction between when code is either imperative or declarative comes down to the degree to which a consumer of a resource needs to manage the state of that resource in order to address it’s concerns. So the higher the degree of management of the resource’s state by the consumer, the greater the degree of the imperative nature of the code and vice versa.
You can get the observable/subject in the parent, and then use the async pipe to pass the value to an @Input. It would look something like this: somePropertySubject$ = this.someService.property$; @Input() iNeedThisProperty: ; If this is not applicable to your case, you can always do different combinations: You can extract the async pipe to a parent element or a ng-container and use the "as" syntax to get the value in a variable and then use that variable in a bunch of places, or if you don't want to use the html template for that (for example, you don't want to hide the elements if the value is not present), you could use some local variable (yes, bad, but in some cases unavoidable), subscribe to the observable in the parent and just assign whatever value passes through the observable/subject to that local variable
One thing you can do if you like the power of rxjs but still want your UI to be declarative is do all your rxjs stuff in services and create a 'pure' component where you async pipe the properties you need to the pure component
While you *can* use rxjs in Vue, I'd do so incredibly sparingly, or not at all. Vue already has reactive primitives (ref, reactive, computed) and so the only benefit to RXJS would be if you wanted to incorporate some complex pipes into the mix. But I'd say typically composables are easier to write and use than RXJS. Take a look at the VueUse library for some good composables. And hey, if you really want to, VueUse also has some composables to allow you to work with RXJS. RXJS is a full toolkit, but frameworks like Vue, Svelte, and Solid have easier ways to deal with reactivity since they have reactive primitives that are built explicitly for their frameworks. The Angular dev team knows RXJS is a pain point and are also looking into simpler reactive primitives.
As a newby developer is the first time I get into declarative vs Imperative. It's blowing my mind! Do you explore all of this more in depth in your course?
@@CptProv 0 ;) it's a completely text-based course, you can find a break down of all the modules/lessons and some previews at angularstart.com if you like
I like the idea of declarative coding with Rxjs observables. What I'm not crazy over is the possibility of having a bunch of unnecessary *ngIf's in the template just so I can use the async pipe and use the value elsewhere. The ngIf's has some overhead and interferes with rendering, and in the case of falsy values it just wouldn't show the element all of which could lead to some edge cases in prod. Do you know of an effective alternative to the *ngIf + async pipe pattern that avoids this in some way? I am aware of packages like RxAngular and NgRx that have structural let directives which can be used as an alternative. Are those something you've used or would try for a better declarative experience?
I use the view model stream approach to deal with this situation, I have a video on that here too: ua-cam.com/video/SXOZaWLs4q0/v-deo.html this allows for just one subscription with the async pipe for the entire template, and there will be no delay in rendering if you use startWith on any async streams. Although this is not the approach I generally use, it is also possible to deal with the falsy values problem by using an object for the ngIf instead (which will always be truthy) that contains a property with an async pipe for the value you want.
ngIf="false" doesn't show your button. [disabled]="!false" will never work. Also : return TERNARY_CONDITION ? true : false, is redundant. Just return TERNARY_CONDITION. Otherwise, nice video :)
Great video Josh. What is your approach regarding ion-refresher and the async pipe? Am I right to assume that as long as ion-refresher itself isn't reactive (throws event ionRefresh, no observable to subscribe to) I have to stick to manually subscribe / unsubscribe in the template's code? Because somehwere you have to do the "this.refresher.complete()" At least if you don't want to overcomplicate things.
Great video as always. One general question: What are your thoughts regarding Angular for the next few years? Will it be relevant and popular among Devs and companies or will it lose with React ultimatey?
You probably shouldn't listen to me, but my gut feeling is that both React and Angular (and Vue) will *very slowly* trend down relative to the newer frameworks, but remain dominant in overall usage for a long time. Likely some of the newer frameworks will find traction, and others will die off. I also think React is likely to lose more usage to the newer frameworks than Angular is - the main justification for that being that a lot of people use React because it is the most used/most popular option, whereas if you are specifically choosing Angular it is likely because of some specific reason.
React js is a blasphemy for JavaScript community. React nonsense must be banned across world plane. This f library makes web development unnecessarily complicated. Angular is far better than svelte and react nonsense., because it leverages rxjs subscription, angular service make communication between sibling components much easier, developers know what exactly is happening. Svelte and react have confusing code. Developer experience matters.
@@Almighty_Flat_Earth Definitely an opinion. I have several years in both frameworks and I personally find React a lot more intuitive. Two way data flow is a nightmare in almost every situation. Reactive forms API is a complete mess. Observables are generally overkill for making simple network requests. Up until recently, forms have been untyped. Form validators have access to set form state. Angular templates don't blend well with typescript. I could go on and on. I mean, I can get my job done using Angular, no doubt, but to say that React is nonsense and Angular is great is just silly.
Good video i have one question that i surf the internet for it no answer, Why not http request not return it as observable but to Promise because ofc API request its hit one time and we don't need to subscribe for multiple change of that call on API, Instead if there a data shared between multiple components then we can update a reactive object as Subjectbehavior on the service? Any idea
I found problems with 'eslint' and declarative programming. Eslint shows an error when I use the service in the class variable before constructor declaration (makes sense). Can any of you tell me how can I handle this situation? Thanks!!!
I like that approach as well. But if don't do subscribe we loose easy way to handle errors. So when we do subscribe, we handle success and error response from API for example. If we pass Observable as in the example - we don't have place how to let View know about error. I think need to introduce some container here, like Either monad.
Good video, though (as many other videos about the topic) it completely neglects an important part: Error Handling. This is where declarative programming get's ugly reaaaallly quick. To stay fully reactive you'd need a second error-observable and such. In the end the code easily explodes from 5 lines to 25 and you can make a strong argument that it made readability and maintainability worse (in many cases)
I've heard this a lot but I don't agree that error handling with this style of programming needs to be ugly - I think the error stream approach is quite nice (it's a bit old now but I have a video on that: ua-cam.com/video/kb9CBd2c4uA/v-deo.html) and typically for "serious" apps I'm using something like NgRx Component Store anyway, which makes accessing errors through a stream easier (again, old video, but that idea is covered somewhat here: ua-cam.com/video/gYzAhW_glqc/v-deo.html)
3:50 Readonly in javascript will lie to you. If itemsLeftInStock is an object, the object reference is readonly, but the internals can change. The observables in HomeComponent can be made readonly which will prevent reassignment of the object while still allowing the objects to reflect underlying changes. I can see this tripping up those new to reactive style programming.
Wow... I thought I was the only one that coded this way... when I write a component now, there's usually nothing below the ngOnInit... if I need an ngOnInit at all.
im working in angular in telephone solutions im using lots of subscribes through rxjs. I need any other alernate solution please share any soure code or docs thanks............
Declaratively is indeed a lot more readable to me. Out of curiosity, what's the tool called again you used to make those pipeline drawings at 8:12 for example?
How would you handle if condition would be like canPurchase and notAlreadyAdded / canPurchase and alreadyAdded ? You knkw, in real-world, there are many many such conditions that are required to be handled from ts file, not only for html template with async, I am not sure why there is no async like pipe for ts file to deal with observables.
No it's not specific to Angular - I don't really know what the trends are in the React space, but newer frameworks like Svelte and Solid have reactivity front and centre
Although there are some use cases for passing an observable as an input, ideally you would be passing values in directly with the async pipe rather than passing the observable itself as an input
@@JoshuaMorony There are cases where more "work/chaining" has to be done on the observable further down in the component chain, so an Observable needs to be passed down. How would you handle this use case?
Hi Joshua, your video was pretty good but I still have a question about declarative. You said that using subscribes to do some stuff was an imperative use of rxjs but is it always possible to do so, on more complex treatments where you would have some side effects? Don't you have any example/idea in mind where you would need to subscribe in your class?
And how would you do if you for example awaits for a user action, that would just emit a value to start a treatment? For example (the example will not be completely relevant but I don't have a better one in mind right now) imagine that you have a form that you filled with your values, then the user registers it on click on a send button and you would like to avoid him for spamming the register button. I would probably create a subject for which I would call next in the template on click, then in my ts I would subscribe to it and use an exhaustMap to let the first treatment be done before the user could initiate a new registration once more. How would you do it more declaratively?
Manual subscribes are still sometimes necessary - if you really want to you can still avoid them, but that doesn't necessarily make it more declarative. A common example is POSTing data, as I think you are illustrating in your example. You could manually subscribe in this case and it could still be declarative - the key part is that the data is leaving your application. If you're coding declaratively, you don't want to subscribe to a stream to pull data out of it, and then set some state somewhere in your application as a result - whatever you just set isn't going to be declarative, but if that data was just being sent off to some server somewhere it doesn't necessarily matter.
You know that your button will never show his disabled state? For me the next step is to remove any logic from the component itself and only react to observable streams and handle the logic in a component store service. In our projects we go even deeper and write actions, reducer and selectors with the help of ngrx
Nice video. I do have a question regarding the usage of observables through the async | pipe What if we require multiple instances of that value in the template? For eg: multiple child components require the value as an input. Is it a good practice to create multiple subscriptions in the template? Or do we wrap it inside an ng-container with ngIf
I think the second approach can cause reflow in the browser. Would love your thoughts on the same. Thanks
This is where I would use the view model/vm$ approach, I have a recent video on that - and even though the combineLatest stream will emit all the values any time any of them change, if you are using OnPush change detection it will only cause the components that actually have had values changed to update
I know using async pipe is really optimal and it feels good doing that but i have one question. How about handling events, is there any "reactive" way to do such things without subscribe . For example when i click on a button i need to alert the current params, or when i need to handle events like modal closed of material lib, ...
I have a video about using a modal reactively/declaratively here if you want to check it out: ua-cam.com/video/vh4WLrqGPEQ/v-deo.html - it's not using the material design components, but it should be the same basic idea - a lot of the time to do something reactively where it otherwise would have required you triggering some imperative code, you would either use a component that you can pass a stream value into via the async pipe (e.g. a modal component that has some kind of isOpen like input), or if the feature you want to use does not already have some kind of declarative API then you might need to wrap it in your own declarative component that calls the imperative API under the hood (if you really want to keep things reactive)
@@JoshuaMorony thanks a lot. I know this is too much but can you suggest a way to interact with router/activatedRoute apis in without subscribing, i always think that it is almost impossible to do such things besides something like [routerLink] which I think is quite limited in use(or I just too dumb to figure out a better way). Thanks again.
Can someone explain how the itemsLeftInStock observable gets decremented in the declarative version? Doesn't this just return the same value over and over?
This isn't actually shown here - the idea would be that you have the itemsInStock stream coming from the service, and you make a call to the service to buy the item. The service will do whatever it needs to do - that might just be nexting a subject in the service itself, or maybe it updates a document in a Firestore database - and the end result will be that the itemsInStock stream will emit its new value which will be received by the component.
Your example of imperative code was the mutation of buyItems but you didn't provide a declarative solution to that. What you missed to include is that declarative coding is just an abstraction on top of imperative coding. Its useful but important to understand.
I’m not sure why people are pushed to program declaratively if they don’t understand how things work imperatively . How can you code declaratively without understanding the lower level which it is abstracted away from?
I don't see it as a problem - I think it is similar to the debate between learning lower level JS fundamentals first versus learning a higher level JS framework first. People fall on different sides of that debate, but certainly you could learn Angular and for a while and not know what document.querySelector is or how to create and insert a DOM node with JS - you'll probably come across those things eventually, but it's not required knowledge to use the framework. You could also argue JS is too high level, and you should really understand the lower level it is abstracted from like the fact that a JS implementation of an array is an abstraction of what would be considered a *real* array in more fundamental computer science. I think it's fine to start at the "surface" which would be the highest level and then dig deeper for additional theory/context as you progress.
@@serbestianmilo1477 no, and i didn't mean it to sound like it applied to the original video but i can see how it could be taken that way. The video is great, its more to the people or lose their minds at the reactive paradigm in general w/o really understanding it.
Firstly, thank you! This is amazingly well done (though your voice is a little too robotic (it feels forced), something to think about :P). Secondly, wow - the code is so much cleaner taking a declarative approach. Will definitely be absorbing this as much as I can for all my future work. Thank you :)
I'm not 100% sure that this is the right way, since Angular itself does not advocate for a complete decorative approach. In the toh tutorial, they use the "imperative approach" according to your definition. They do not say that there is a better approach, hence others example they provide would be also considered as 'imperative'. Could you show a simple ToDo tutorial with your decorative approach ? Plus what is the impact on performance of an Angular app, while creating stream of data everywhere ?
The imperative mental model is more intuitive and simple to most people, the payoff of a declarative approach generally takes time/effort, so I don't think we are going to be seeing the Angular team recommend this in their docs. I don't want this to sound dismissive of the imperative approach as I'm sure plenty of great Angular developers do use it, but at least from the people I know I've found that more advanced Angular developers tend to move toward a more reactive/declarative approach. Here is an example of a *mostly* declarative todo style app - it was intended more for a beginner level, so some imperative shortcuts were taken as to not overwhelm with too many concepts at once: github.com/joshuamorony/ionicstart-quicklists - and if you're interested in a more advanced declarative style app: github.com/joshuamorony/ionicstart-chat Edit: oh and about performance, the usage of RxJS is going to be negligible for typical app building purposes. These "streams of data" are really just functions being called behind the scenes, not like some active connection like a web socket or something.
I'm a bit sad to watch this video, it's missing some key points. - You didnt show how to reimplement you "BuyItem" function => i think it's a big mistake in the video (You could have done it with SubjectBehaviour in a Service, or an other way) - ReactiveForm=>ValueChange => Subscribe => I think many dev that try to go the Declarative route are stuck there - Showing UserAuthentication with the CanPurchase in image instead of code not really help other to understand i think you can do better in a lot of parts of this video, keep up your work but review your things to check if everything you wanted to demonstrate is really demonstrated
No the definition I go by means that declarations/variables aren't reassigned, so whilst I wouldn't like "p = this.aService.t()" for other reasons, from a declarative perspective it's fine as long as "p" is not reassigned to something else later
6:45 the ngif + disabled bith using the canPurchase doesn't make sense. If it is false, the buy-Button wont get rendered. no need to Set it to disabled. What a shame that angular does not have template variables outside of ngif/ngfor. imagine *ngLet="let x = something$| async" which does nothing except declaring a local template variable
Good catch, my fault for not actually running this code! Fortunately doesn't effect the message of the video, probably just makes me look a little silly
@@JoshuaMorony it's actually very nice showing that you're also human Joshua and we all make mistakes. Even being uberproangularmeisterdeveloper :) that's number one lesson if someone is willing to be software developer of any kind.
Declartive Coding: "You specify all dependencies at declaration time": sample: in one line you see what is happening: const first10FruitProducts$ = products$.pipe(filter (p => p.category === 'fruit') take(10 ) ).subscribe(renderProduct)
there is nothing better (or more imperative) with the template code you are now forced to use here: this is not an improvement, just disabled the button with a component boolean and don't introduce the async pipe here, it does not buy you any cleaner code.
This logic should be in the service, not in the component. In my opinion it should have similar method that will return that observable like this: canPurchase$ = this.itemService.IsItemsInStock$;
I appreciate a lot this explanation. Finding variables through the code is always a mess for me. But I dont understand the last code example. The buyItem method is empty and said that is managed by observable... But how? Can someone give me some hint? Thanks
Been a while since I looked at this code but yeah that code sample leaves a little too much to the imagination (especially since the method isn't even bound to clicking the button). Anyway the general idea here is that when the button is clicked it triggers some process in the itemsService (maybe we next some subject when the buy item is clicked like: itemsService.purchase$.next(itemId)). Within the itemsService, whatever needs to happen as a reaction to that happens, and ultimately the "itemsInStock$" observable would emit a new value as a result
@@JoshuaMorony just i thinked. Thanks for the reply, I just wanted to be sure of my interpretation
@@davidechierici9182 Thanks for asking this question and answer. I was having the same question 🙂
Observables and RxJS operators are a game changer.
That being said, RxJS is also a powerful foot-gun and it is easy to get yourself into a situation where your declarative pipes are every bit as convoluted and even harder to debug than straightforward imperative code. This is especially true when combining observables.
I find observables harder to debug almost every single time, because the stack trace is very muddy (by definition), the whole point of the observables is decoupling the "catalyst" from the "results". This breakage makes it very hard to look at a result and determine its catalyst. In our app, we've had many components that started out imperative and then were rewritten declaratively to handle some race conditions, only to be simplified back down into imperative code again when they became too complex to debug.
@@BenjaminLeeds Would you mind sharing some examples so that others can learn from them?
@@BenjaminLeeds that sounds like your approach was flawed. Rxjs is a dream for handling race conditions. It really shines when you make each observable as small as possible and embrace the single responsibility principal. Eventually rxjs code starts to read like english! If your observables are setup correctly their dependencies should be clear and almost similar to a pure component where it only relies on the inputs and outputs with no side effects.
@@ImperiumLibertas If I could sum up my experience with Angular and with RxJs inside of Angular it would be this:
"I wish I was smarter so I could write good Angular code, but I'm not smarter, so I wish I wasn't writing Angular."
My approach was probably flawed. I prefer solutions that don't encourage flawed approaches, because probably if I'm doing it poorly, my teammates are as well.
@@BenjaminLeedsI love Angular, but your comment is a great example as to why Angular isn't more popular.
I think the key reason you should work declaratively as much as possible is that your main goal with any component should be to minimize state as much as possible. That means as few writable or mutable public properties as humanly possible within your component. This holds true for any component based web framework.
One of the most valuable videos on the internet, simple and fabulous, more people should know these techniques.
You are so great at explaining challenging topics and have really improved your presentation style. When I first saw your videos I was a bit overwhelmed by your focus on ionic, but even then you still had really good Angular content. I see you've recently done a lot more Angular and the quality of your videos is even better now so really excited to see more videos from you. I think you will reach 1 million subscribers. You are special.
It’s a great idea to confine the logic of how a value gets calculated to a single spot, even if you’re not using declarative/functional patterns explicitly. I use Lightning Web Components at work, a different frontend framework that lacks RXjs’ rich declarative library. For every bit of state that gets exposed from my components, I have a single “setThisValue” function that reads all the surrounding state it needs to calculate and set that value. I think imperatively call that “setThisValue” function any time that value might need a refresh
Recently, I'm just get into learning how to code reactively and I found your videos super useful. Thank you for all your videos and hope that there will be more about this topic
Every time I watch your videos I learn something new. Thanks for the awesome content!
As someone who also uses more the declarative approach, I like the video. One suggestion though, when using a ternary operator, you don't need " ? true : false" since the left side of the ? operator (condition) already returns a boolean, right? That's the point of a ternary operator. So we can just use and return that value. In this case at 6:10 it would be:
map(itemsLeftInStock => itemsLeftInStock > 0)
I always get triggered by this, when seeing it in the PRs, since it's redundant.
I noticed the same thing
I found this video incredibly useful. 6 months after switching to Angular from React I am not declarative 100% but I end up always subscribe to observablels as a part of my brain still tells me that I need to "own" those state values by storing them in variables. The example you are showing here is a lot smoother and shows me I still have along way to go and adjust to this mindset. I would like to become a pro member on your platform but for the moment I am not interested in Ionic but purely on Angular. I was wondering if you have more courses going to be added on that..! Not judging, I think that what you are doing is great is just that I am not into mobile apps rn
I am planning to do an "Angular only" flavour of Ionic Start soon, but Ionic Start already is mostly just an Angular course where you are using Ionic UI components instead of something like Material Design components
It's sort of interesting to me reading that you switched from React to Angular. These days I normally hear the opposite.
I'm glad about that, since I've always preferred Angular over React.
@@WolfElectronicS well I ended up leading a team which is experienced in Angular and forcing them to switch to React would've taken too long... However I ended up enjoying the built in tools Angular comes with but there are some things like forms which ended up being way too complicated for what it needs to do really. Also having a route-aware menu in React is as simple as using a hook while in Angular you might end up subscribing to the router events, finding the Navigation end... I mean this is way more verbose than it should be and IMO Angular has some work to do in smoothing some rough edges but so far it has proven to be more reliable than Next JS which would randomly require me to edit bits and pieces of the framework I don't feel I should've touched
@@WolfElectronicS React js is a blasphemy for JavaScript community. React nonsense must be banned across world plane. This f library makes web development unnecessarily complicated.
Angular is far better than svelte and react nonsense., because it leverages rxjs subscription, angular service make communication between sibling components much easier, developers know what exactly is happening.
Svelte and react have confusing code. Developer experience matters.
So, I'm currently focusing on wrapping my head around wave function collapse and am almost there. That's how I found your channel this morning. Got this vid in my recommended figured I'd give it a shot. Been procrastinating on learning more of Angular and a lot of tutorials for it don't leave me feeling like I really understand what I'm doing or what's happening. But this gave me a whole lot in 9 minutes- it gave me some why's and how's for best practices, and doesn't overload with every bit of information to know at once. But just as importantly, it made me aware of weaknesses- the only thing I still don't follow understand is promises and obversables. But, I'm left with those two alone, and not 500 other things I'm super stressed about learning. One step at a time though, got a concrete thing to work on now.
This is a really cool comment to read, thank you - and I like that you found the channel through one of the few non-Angular videos I've published recently. As for promises and observables, I also have a recent video that might help provide some context: ua-cam.com/video/vdsujUhFMLY/v-deo.html
Speaking as a newbie to Angular, I personally lack some background knowledge to understand the concepts. Most of the background knowledge is around RxJS & other Angular concepts. Might link another video you have that covers those topics for people starting out. Really fascinating video, exposed me to a number of topics, so cheers!
Very nicely explained. The key idea is that a simple variable represents a single value, but a stream represents all of the values at once
This video is probably the best to explain declarative. I was struggling to explain declarative to new people 😅
Fantastic explanation
I've just started using Angular and RxJS and I knew right from the start that I was missing something. This coding style looks unnatural at first, but now I'm starting to understand it's benefits.
I love the way how you explain things, it is pretty close to me, I can't stop watching 😍
Nice. Never heard about the concept, but always intuitively aimed for that.
The data flow must be crystal clear in Angular.
I have been down this road myself. One thing I would like to add is that part of the power of this library comes in the form of functional programing. Although the Observer pattern is more flashy because makes it "reactive" it is only one part of the equation the other is in reality functional programming with all the great things it has like pure functions and thus avoiding side effects and of curse like you mention a few times :) makes the code declarative rather than imperative. The declarative part comes from functinal programming and not from Observer pattern.
Join my mailing list for more exclusive content and access to the archive of my private tips of the week: mobirony.ck.page/4a331b9076
Nice. Signals simplifies the declarative approach even further starting in v16
This is a really great video and I'm going to show it to our other devs. I'm also glad that because it's informative and practical, the comment section isn't going to devolve into ribbing you like the last several more...experimental...videos.
Would be interesting to see your view on the corresponding ItemsService implementation, like receiving list of items from server, adding/removing some, sorting etc.
I have a video idea / challenge for you -- Fully reactive Tour of Heroes app.
oh Man You just inspired me to make few awesome changes in my code to make it better! This is fantastic!
I want more videos like this for common and more complex use cases
Most of my videos use this approach, so there should already a bunch of uses cases for you to look through if you want (even if the video isn't specifically about using the declarative approach) and of course my future videos will also be using this approach too
I'm a big fan of your content, Josh. G'day from Mooloolaba, QLD 👍
I think for me the distinction between when code is either imperative or declarative comes down to the degree to which a consumer of a resource needs to manage the state of that resource in order to address it’s concerns. So the higher the degree of management of the resource’s state by the consumer, the greater the degree of the imperative nature of the code and vice versa.
How do you handle reactivity with @Input ? Do you use Subjectize ? Do you pass Observables in Input ?
You can get the observable/subject in the parent, and then use the async pipe to pass the value to an @Input.
It would look something like this:
somePropertySubject$ = this.someService.property$;
@Input() iNeedThisProperty: ;
If this is not applicable to your case, you can always do different combinations:
You can extract the async pipe to a parent element or a ng-container and use the "as" syntax to get the value in a variable and then use that variable in a bunch of places,
or if you don't want to use the html template for that (for example, you don't want to hide the elements if the value is not present), you could use some local variable (yes, bad, but in some cases unavoidable), subscribe to the observable in the parent and just assign whatever value passes through the observable/subject to that local variable
Pass observable with async pipe and inside component use setter to emit the value on a internal BehaviorSubject
Sometimes I did this way and sometimes I didn't. Benefit of it wasn't obvious for me. Now I will look at this differently, good examples
Nicely explained
thank for your sharing
One thing you can do if you like the power of rxjs but still want your UI to be declarative is do all your rxjs stuff in services and create a 'pure' component where you async pipe the properties you need to the pure component
I'm currently migrating my huge project to declarative. Painful but so good
This is the missing part I needed to use my global state properly. Thanks!! (Wish me luck for the refactoring)
Great post, and right on time (for me).
Thanks Nice example!
Great video as usual! Thanks.
Really nice video!
Is it possible to get source code for this? Or at least the service code to handle items stock? Thank you!!
I wish he still coded for the buy function… however, great video!
i waited for that too,cause I tried to do it in my mind and gave up so I could see his solution
is it possible to trigger submit button buy without subscribe to the service ?
What I’d be interested in seeing is the proper use of RxJS across React/Vue and of course Angular.
While you *can* use rxjs in Vue, I'd do so incredibly sparingly, or not at all. Vue already has reactive primitives (ref, reactive, computed) and so the only benefit to RXJS would be if you wanted to incorporate some complex pipes into the mix. But I'd say typically composables are easier to write and use than RXJS. Take a look at the VueUse library for some good composables. And hey, if you really want to, VueUse also has some composables to allow you to work with RXJS.
RXJS is a full toolkit, but frameworks like Vue, Svelte, and Solid have easier ways to deal with reactivity since they have reactive primitives that are built explicitly for their frameworks. The Angular dev team knows RXJS is a pain point and are also looking into simpler reactive primitives.
As a newby developer is the first time I get into declarative vs Imperative. It's blowing my mind! Do you explore all of this more in depth in your course?
Yep! Writing code declaratively with Angular is pretty much what most of the course is about
@@JoshuaMorony Very cool! Just out of curiosity before I buy it, how many hours of vid are in the course?
@@CptProv 0 ;) it's a completely text-based course, you can find a break down of all the modules/lessons and some previews at angularstart.com if you like
I like the idea of declarative coding with Rxjs observables. What I'm not crazy over is the possibility of having a bunch of unnecessary *ngIf's in the template just so I can use the async pipe and use the value elsewhere. The ngIf's has some overhead and interferes with rendering, and in the case of falsy values it just wouldn't show the element all of which could lead to some edge cases in prod. Do you know of an effective alternative to the *ngIf + async pipe pattern that avoids this in some way? I am aware of packages like RxAngular and NgRx that have structural let directives which can be used as an alternative. Are those something you've used or would try for a better declarative experience?
I use the view model stream approach to deal with this situation, I have a video on that here too: ua-cam.com/video/SXOZaWLs4q0/v-deo.html this allows for just one subscription with the async pipe for the entire template, and there will be no delay in rendering if you use startWith on any async streams. Although this is not the approach I generally use, it is also possible to deal with the falsy values problem by using an object for the ngIf instead (which will always be truthy) that contains a property with an async pipe for the value you want.
I think using Ngrx-Store's architecture pushed me to code declarative by default.
That is the way. Also map((itemsLeftInStock) => itemsLeftInStock> 0) is enough but I guess you already know it !
Nice job, bro
ngIf="false" doesn't show your button.
[disabled]="!false" will never work.
Also : return TERNARY_CONDITION ? true : false, is redundant. Just return TERNARY_CONDITION.
Otherwise, nice video :)
Great video Josh. What is your approach regarding ion-refresher and the async pipe? Am I right to assume that as long as ion-refresher itself isn't reactive (throws event ionRefresh, no observable to subscribe to) I have to stick to manually subscribe / unsubscribe in the template's code? Because somehwere you have to do the "this.refresher.complete()"
At least if you don't want to overcomplicate things.
Great video as always. One general question: What are your thoughts regarding Angular for the next few years? Will it be relevant and popular among Devs and companies or will it lose with React ultimatey?
You probably shouldn't listen to me, but my gut feeling is that both React and Angular (and Vue) will *very slowly* trend down relative to the newer frameworks, but remain dominant in overall usage for a long time. Likely some of the newer frameworks will find traction, and others will die off. I also think React is likely to lose more usage to the newer frameworks than Angular is - the main justification for that being that a lot of people use React because it is the most used/most popular option, whereas if you are specifically choosing Angular it is likely because of some specific reason.
React js is a blasphemy for JavaScript community. React nonsense must be banned across world plane. This f library makes web development unnecessarily complicated.
Angular is far better than svelte and react nonsense., because it leverages rxjs subscription, angular service make communication between sibling components much easier, developers know what exactly is happening.
Svelte and react have confusing code. Developer experience matters.
@@Almighty_Flat_Earth Definitely an opinion. I have several years in both frameworks and I personally find React a lot more intuitive. Two way data flow is a nightmare in almost every situation. Reactive forms API is a complete mess. Observables are generally overkill for making simple network requests. Up until recently, forms have been untyped. Form validators have access to set form state. Angular templates don't blend well with typescript. I could go on and on. I mean, I can get my job done using Angular, no doubt, but to say that React is nonsense and Angular is great is just silly.
Great great great video
did you forget to add the takeUntil or is it unnecessary for some reason?
Good video i have one question that i surf the internet for it no answer,
Why not http request not return it as observable but to Promise because ofc API request its hit one time and we don't need to subscribe for multiple change of that call on API, Instead if there a data shared between multiple components then we can update a reactive object as Subjectbehavior on the service? Any idea
I found problems with 'eslint' and declarative programming. Eslint shows an error when I use the service in the class variable before constructor declaration (makes sense). Can any of you tell me how can I handle this situation? Thanks!!!
I like that approach as well. But if don't do subscribe we loose easy way to handle errors. So when we do subscribe, we handle success and error response from API for example. If we pass Observable as in the example - we don't have place how to let View know about error. I think need to introduce some container here, like Either monad.
Good video, though (as many other videos about the topic) it completely neglects an important part: Error Handling. This is where declarative programming get's ugly reaaaallly quick. To stay fully reactive you'd need a second error-observable and such. In the end the code easily explodes from 5 lines to 25 and you can make a strong argument that it made readability and maintainability worse (in many cases)
I've heard this a lot but I don't agree that error handling with this style of programming needs to be ugly - I think the error stream approach is quite nice (it's a bit old now but I have a video on that: ua-cam.com/video/kb9CBd2c4uA/v-deo.html) and typically for "serious" apps I'm using something like NgRx Component Store anyway, which makes accessing errors through a stream easier (again, old video, but that idea is covered somewhat here: ua-cam.com/video/gYzAhW_glqc/v-deo.html)
Awesome!
3:50 Readonly in javascript will lie to you. If itemsLeftInStock is an object, the object reference is readonly, but the internals can change. The observables in HomeComponent can be made readonly which will prevent reassignment of the object while still allowing the objects to reflect underlying changes. I can see this tripping up those new to reactive style programming.
Wow... I thought I was the only one that coded this way... when I write a component now, there's usually nothing below the ngOnInit... if I need an ngOnInit at all.
im working in angular in telephone solutions im using lots of subscribes through rxjs. I need any other alernate solution please share any soure code or docs thanks............
Declaratively is indeed a lot more readable to me. Out of curiosity, what's the tool called again you used to make those pipeline drawings at 8:12 for example?
That's Excalidraw and I also have some emojis edited in on top of it from my video editing software
How would you handle if condition would be like
canPurchase and notAlreadyAdded / canPurchase and alreadyAdded ?
You knkw, in real-world, there are many many such conditions that are required to be handled from ts file, not only for html template with async,
I am not sure why there is no async like pipe for ts file to deal with observables.
Is reactive coding specific to angular? Or are people in react world also doing it?
No it's not specific to Angular - I don't really know what the trends are in the React space, but newer frameworks like Svelte and Solid have reactivity front and centre
Thanks!
How would you do it if the observable is passed in via @Input()? I am guessing there still need to be all the ngOnInit boilerplate?
Although there are some use cases for passing an observable as an input, ideally you would be passing values in directly with the async pipe rather than passing the observable itself as an input
@@JoshuaMorony There are cases where more "work/chaining" has to be done on the observable further down in the component chain, so an Observable needs to be passed down. How would you handle this use case?
Hi Joshua, your video was pretty good but I still have a question about declarative. You said that using subscribes to do some stuff was an imperative use of rxjs but is it always possible to do so, on more complex treatments where you would have some side effects? Don't you have any example/idea in mind where you would need to subscribe in your class?
And how would you do if you for example awaits for a user action, that would just emit a value to start a treatment?
For example (the example will not be completely relevant but I don't have a better one in mind right now) imagine that you have a form that you filled with your values, then the user registers it on click on a send button and you would like to avoid him for spamming the register button. I would probably create a subject for which I would call next in the template on click, then in my ts I would subscribe to it and use an exhaustMap to let the first treatment be done before the user could initiate a new registration once more. How would you do it more declaratively?
Manual subscribes are still sometimes necessary - if you really want to you can still avoid them, but that doesn't necessarily make it more declarative. A common example is POSTing data, as I think you are illustrating in your example. You could manually subscribe in this case and it could still be declarative - the key part is that the data is leaving your application. If you're coding declaratively, you don't want to subscribe to a stream to pull data out of it, and then set some state somewhere in your application as a result - whatever you just set isn't going to be declarative, but if that data was just being sent off to some server somewhere it doesn't necessarily matter.
@@JoshuaMorony Okay so that's exactly what I do, thanks for your explanations :)
You know that your button will never show his disabled state?
For me the next step is to remove any logic from the component itself and only react to observable streams and handle the logic in a component store service.
In our projects we go even deeper and write actions, reducer and selectors with the help of ngrx
Nice video. I do have a question regarding the usage of observables through the async | pipe
What if we require multiple instances of that value in the template? For eg: multiple child components require the value as an input.
Is it a good practice to create multiple subscriptions in the template?
Or do we wrap it inside an ng-container with ngIf
I think the second approach can cause reflow in the browser. Would love your thoughts on the same. Thanks
You can use the sharedReplay operator if you have multiple async variables of the same name
This is where I would use the view model/vm$ approach, I have a recent video on that - and even though the combineLatest stream will emit all the values any time any of them change, if you are using OnPush change detection it will only cause the components that actually have had values changed to update
6:29 Wouldn't this straight up hide the button, rendering the disabled property useless?
That's true. I was thinking about this also :)
I know using async pipe is really optimal and it feels good doing that but i have one question. How about handling events, is there any "reactive" way to do such things without subscribe . For example when i click on a button i need to alert the current params, or when i need to handle events like modal closed of material lib, ...
I have a video about using a modal reactively/declaratively here if you want to check it out: ua-cam.com/video/vh4WLrqGPEQ/v-deo.html - it's not using the material design components, but it should be the same basic idea - a lot of the time to do something reactively where it otherwise would have required you triggering some imperative code, you would either use a component that you can pass a stream value into via the async pipe (e.g. a modal component that has some kind of isOpen like input), or if the feature you want to use does not already have some kind of declarative API then you might need to wrap it in your own declarative component that calls the imperative API under the hood (if you really want to keep things reactive)
@@JoshuaMorony thanks a lot. I know this is too much but can you suggest a way to interact with router/activatedRoute apis in without subscribing, i always think that it is almost impossible to do such things besides something like [routerLink] which I think is quite limited in use(or I just too dumb to figure out a better way). Thanks again.
Saying that
*ngIf="chanPurchase$ | async as canPurchase" [disabled]="!canPurchase"
is readable makes me really sad.
Nice. So you can be imperative in services, heavily unit test that, and be declarative in your components.
Looks like something that React and Vue already does out of the box and by default.
how is this default in react in any way?
Can someone explain how the itemsLeftInStock observable gets decremented in the declarative version? Doesn't this just return the same value over and over?
This isn't actually shown here - the idea would be that you have the itemsInStock stream coming from the service, and you make a call to the service to buy the item. The service will do whatever it needs to do - that might just be nexting a subject in the service itself, or maybe it updates a document in a Firestore database - and the end result will be that the itemsInStock stream will emit its new value which will be received by the component.
@@JoshuaMorony Thank you, now I get it!
Your example of imperative code was the mutation of buyItems but you didn't provide a declarative solution to that. What you missed to include is that declarative coding is just an abstraction on top of imperative coding. Its useful but important to understand.
He did say that in the video.
Do you code using other frameworks as well?
I also use React/Gatsby and am getting more into SvelteKit now - others I have only toyed with a little
I’m not sure why people are pushed to program declaratively if they don’t understand how things work imperatively . How can you code declaratively without understanding the lower level which it is abstracted away from?
I don't see it as a problem - I think it is similar to the debate between learning lower level JS fundamentals first versus learning a higher level JS framework first. People fall on different sides of that debate, but certainly you could learn Angular and for a while and not know what document.querySelector is or how to create and insert a DOM node with JS - you'll probably come across those things eventually, but it's not required knowledge to use the framework.
You could also argue JS is too high level, and you should really understand the lower level it is abstracted from like the fact that a JS implementation of an array is an abstraction of what would be considered a *real* array in more fundamental computer science. I think it's fine to start at the "surface" which would be the highest level and then dig deeper for additional theory/context as you progress.
Reactive coding is like OOP: < 10% will actually 'get it' but > 90% will have opinions on it.
are you an indian? idk that just seems like such an indian thing to say
@@serbestianmilo1477 no, and i didn't mean it to sound like it applied to the original video but i can see how it could be taken that way. The video is great, its more to the people or lose their minds at the reactive paradigm in general w/o really understanding it.
@@serbestianmilo1477 How did you get "this guy is Indian" from that sentence?
I don't think so, its easy to say which code is more reactive than the other, but its difficult to say which oop design is better
I don’t know what that comment is supposed to mean or imply.
IMO declarative code is like saying “Let there be light” instead of showing the implementation detail of how light gets created.
"Isn't this all just a bunch of bs on top of loops?"
I don't have the heart to tell them loops are just a bunch of bs on top of GOTO
Firstly, thank you! This is amazingly well done (though your voice is a little too robotic (it feels forced), something to think about :P).
Secondly, wow - the code is so much cleaner taking a declarative approach. Will definitely be absorbing this as much as I can for all my future work. Thank you :)
I'm not 100% sure that this is the right way, since Angular itself does not advocate for a complete decorative approach. In the toh tutorial, they use the "imperative approach" according to your definition. They do not say that there is a better approach, hence others example they provide would be also considered as 'imperative'. Could you show a simple ToDo tutorial with your decorative approach ? Plus what is the impact on performance of an Angular app, while creating stream of data everywhere ?
The imperative mental model is more intuitive and simple to most people, the payoff of a declarative approach generally takes time/effort, so I don't think we are going to be seeing the Angular team recommend this in their docs. I don't want this to sound dismissive of the imperative approach as I'm sure plenty of great Angular developers do use it, but at least from the people I know I've found that more advanced Angular developers tend to move toward a more reactive/declarative approach.
Here is an example of a *mostly* declarative todo style app - it was intended more for a beginner level, so some imperative shortcuts were taken as to not overwhelm with too many concepts at once: github.com/joshuamorony/ionicstart-quicklists - and if you're interested in a more advanced declarative style app: github.com/joshuamorony/ionicstart-chat
Edit: oh and about performance, the usage of RxJS is going to be negligible for typical app building purposes. These "streams of data" are really just functions being called behind the scenes, not like some active connection like a web socket or something.
e a equipe do Angular pensando em deixar de lado o RXJS, parece brincadeira
`? true : false` makes me so sad 😢
Try functional programming first, then declarative coding will be much natural
Imperative team FTW
I'm a bit sad to watch this video, it's missing some key points.
- You didnt show how to reimplement you "BuyItem" function => i think it's a big mistake in the video (You could have done it with SubjectBehaviour in a Service, or an other way)
- ReactiveForm=>ValueChange => Subscribe => I think many dev that try to go the Declarative route are stuck there
- Showing UserAuthentication with the CanPurchase in image instead of code not really help other to understand
i think you can do better in a lot of parts of this video, keep up your work but review your things to check if everything you wanted to demonstrate is really demonstrated
2:15 lol so you think declarative means methods with good names, what a joke.
No the definition I go by means that declarations/variables aren't reassigned, so whilst I wouldn't like "p = this.aService.t()" for other reasons, from a declarative perspective it's fine as long as "p" is not reassigned to something else later
TypeScript compiler is telling me `this.itemsService` is used before initialization. Any nice way to get around this without a `// @ts-ignore`?
7:00 can be shortened to just
canPurchase$ = this.itemsLeftInStock$.pipe(
map((itemsLeftInStock) => (itemsLeftInStock >0))
);
right?
Yep you could do that
I'd go with
map(itemsLeftInStock => itemsLeftInStock > 0)
Never understood why people use a lot of unnecessary parentheses
Yes, I always mark code like this in code reviews.
6:45 the ngif + disabled bith using the canPurchase doesn't make sense. If it is false, the buy-Button wont get rendered. no need to Set it to disabled. What a shame that angular does not have template variables outside of ngif/ngfor. imagine *ngLet="let x = something$| async" which does nothing except declaring a local template variable
Good catch, my fault for not actually running this code! Fortunately doesn't effect the message of the video, probably just makes me look a little silly
@@JoshuaMorony nono dont u worry, great Video 👍🏻
about the ngLet thing: I might try to implement it myself. I really feels useful
@@JoshuaMorony it's actually very nice showing that you're also human Joshua and we all make mistakes. Even being uberproangularmeisterdeveloper :) that's number one lesson if someone is willing to be software developer of any kind.
@@endlacer NgLet already exist but it f*cks up the type. You'll get an "any" for some reason and believe me this is bad
I mean it doesn't exist natively but tons of people have created plugins for that. But they all lose the typing for some reason
Declartive Coding: "You specify all dependencies at declaration time":
sample: in one line you see what is happening:
const first10FruitProducts$ = products$.pipe(filter (p => p.category === 'fruit')
take(10 )
).subscribe(renderProduct)
there is nothing better (or more imperative) with the template code you are now forced to use here:
this is not an improvement, just disabled the button with a component boolean and don't introduce the async pipe here, it does not buy you any cleaner code.
The subtle way how music enter when the video is about to end🤌🏻
canPurchase$ = this.itemsLeftinStock$.pipe(map(itemsLeftInStock => itemsLeftInStock > 0))
FixT :P
This logic should be in the service, not in the component.
In my opinion it should have similar method that will return that observable like this:
canPurchase$ = this.itemService.IsItemsInStock$;