Lucas_Paganini:
Hey, welcome to Adventures in Angular, the podcast where we keep you updated on all things Angular related. This show is produced by two companies, Top End Devs and Unvoid. Top End Devs is where we create top end devs who get top end pay and recognition while working on interesting problems and making meaningful community contributions. And Unvoid, which offers remote design and web development services with specialization in Angular. for companies that truly care about quality. In today's episode, we'll talk about advanced patterns with Angular directives. Again, two episodes ago, we had Armin on the show to talk about advanced use cases for directives in Angular. But there is so much content that we couldn't cover everything in that episode. So today, Armin is back for a part two on advanced patterns with Angular directives. My name is Lucas Paganini. I'm the CEO of Unvoid and your host in the podcast. Joining me in today's episode is Armen Vardanyan.
Armen_Vardanyan:
Hey everyone! Happy to be back and talk about Directive More. It's been a big topic for me the last two months.
Lucas_Paganini:
It was an excellent episode. So for those of you that haven't listened to that episode yet, it's just two episodes before this one. So I recommend that you listen to that before you listen to this episode, because this will give you more context on everything that we're talking about here. So we're not going to go over everything that we covered in that episode, but this is a continuation from there. So highly recommend checking that out. So, Armin. Basically, in the last episode that we talked about directives, we covered three of the five articles that you already wrote in your series about directives. And as you mentioned last time, you're still adding more articles. So if any of you wants to read the articles instead of just consuming the podcast, then the link... to the entire series is gonna be in the show notes. So you can go there, give a like, comment on Armand's post and make sure that you share it with all your colleagues that can learn from this. But basically we only covered the first three ones, right? And do you want to just briefly go over those three ones just kind of in a two minute run just so that we can. contextualize everyone that maybe listened to the episode, but don't fully remember everything. And then we can go over the fourth and fifth and even second article that is still in the works.
Armen_Vardanyan:
Absolutely, that makes sense. So we had like three use cases for directives. The first one was using directive exported references in order to communicate stuff to the component template. So in that example we built a password strength meter that applied to all input of type password. and then we took the reference of the directive and it sort of told us what was the strengths of the password so we could use it and for example display a range or display a message or display a validation notice or whatever. So that was the first article. In the second one we covered using structural directives to simplify content projection. We did a loading component in which we could project content. and depending on a boolean it would block the content and show a spinner over it. And for that, to simplify the template and not to have like passed the projected content into this component all the time, we built a directive and explored some capabilities of the view container ref and used the view container ref to project our content into this dynamically created loader. So the template got simpler. but it was the same functionality so we didn't need to use the to use the content projection on that component directly all the time. And the third one was about hijacking existing elements or components. So for example we built a external link directive that would find all the anchor tags that have an href that is pointing out. our application, so external links, and used it to kind of automatically add a target blank attribute to it, which, you know, if we have the policy to always open external links in a new tab, that with just that directive it will just work all over our application. Okay, so there is that... I think those are the general use cases we already covered. So maybe we can already dive into the new ones.
Lucas_Paganini:
Certainly, yeah, I think that was a really good wrap up of everything. All right, and again, if any of you are interested in diving deeper in those examples that Armen just talked about, you should check out the two episodes ago where we did the part one of advanced patterns with Angular directives. So, all right, what do we do from here, Armen? How can we extract even more value from Angular directives?
Armen_Vardanyan:
Okay, let's talk about events. And events are a part of Angular that we always sort of take for granted. Like we know we wrap the name of the event in those round brackets, and we write some expression or maybe a function call, and that's it for us, we don't really bother. We know that we can use event-digniter to send an event from a component or directive. Interesting. And that's it, that's generally it. But there's really... a bit more flexibility to what we can achieve with directives here. So first use case I show in my article is about a sort of click away event. Sometimes we need to do something when the user click outside of a certain element. And if we want to have that functionality usable, we probably should use a directive. So what we can do in this scenario, we can write a directive and let's say, call it click away, for example. And then we can just have an event emitter that will emit any time that somewhere in the document, this user clicks and not in that element. Okay, that's the mundane part. What is interesting there is that we can use, we can use the name of the event emitter. to select for the directive. So, for example, if you are building a directive that has the same input that the selector of the directive, for example, you have a directive named, I don't know, X, and you have an input on that directive named X. So in the template we can just do square brackets X equals something and simultaneously we both apply the directive. also pass the input. So it turns out that you can do the same with outputs. We can just name our directive, the selector, click away as an attribute, and then we can create an event emitter also named click away. And then in the template we need to just drop the name click away, okay, and say, you know, equals an expression, maybe a function call. And it will work in the way that like, as a custom event, as another custom event, but you can do that with any template element, any HTML element, any component. And that is a really cool use case. So like another example from the same article is building sort of infinite scroll or doing something when an element scrolls into the, viewport, again, using with the directive. So essentially what I want is a custom event that I will put on an HTML element and say, when this happens, when this element is scrolled into view, do this in the same way that I'm registering. I don't know, click events, double click events, and so on. So in order to do that, we employ the same mechanism and use an intersection observer. And essentially, that's it. You can go further and modify the behavior, you can add inputs or whatever, it's just the casual directive, it just allows you to use it in a way that is very understandable. Like, it's very obvious for any developer who even doesn't know that you can do something. When they see an event called scroll into view, it's readily apparent that this handler will fire when this, I don't know, div scrolls into the viewport. So that makes your template really, really easily readable and also that functionality is 100% reasonable, drop it on an element. So this way you can make custom events, you can make flexible stuff, you can, I don't know, combine events from different elements if you want. You have the access to the template ref, if you are building, for example, structural directive. So... My general advice about this is that don't forget that directives are sort of components without templates. So they have everything. It's just that they don't have their own templates. They still can, if you build a structural directive, you still get the other template, for example, right? So you can do anything that you do in the component. It's okay to put, I don't know, business logic there too. We're gonna talk about that in the next use case. Okay, so yeah, in general, that's how I can work with the events using direct. This really helps me enhance my templates.
Lucas_Paganini:
Okay, so basically the trick here is that you're creating a directive which emits a specific value at a specific point. So the whole responsibility of that directive is to emit an event and then the parent element or even the host element can, will decide what to do with that information and when to react to it. And then the trick is, since your directive is mainly responsible for emitting an event, then you can use the directive selector, the attribute selector for the directive, you can use the same attribute to name the output event of the directive, and then you can have a single selector that, at the same time that it is applying the directive, it's also binding to the event that directive is emitting. Nice.
Armen_Vardanyan:
Angular really loves SyntaxX Sugar and I enjoy it a lot. Why write more boilerplate if we can just express it in one single line? I mean, I'm not, there are people that are like, oh, let's remove as much code as possible, but I'm for readability. If the code is short and easily understandable, then cool. If the code is short and feels like magic, then it's better to have more lines of code that are more explicit. naming and extracting stuff to functions help. I find that sometimes thinking about directives as essentially functions that get applied to HTML elements is useful in that context because the most basic building block is a function like one of the first ones that you learn when you come into software development and functions are really good because you get to name stuff, you get Instead of writing a comment that explains something, instead of trying to find, oh, how do I structure these 10 lines of code so it's more understandable, you can just extract it to a function and call it, you know, do this. And it will be understandable. It probably won't be understandable if you have still bad code in the function, but it would at least somewhat improve the general code. So directives help to achieve the same thing. Sometimes we do stuff in the components that... really don't belong there in the sense that, you know, why not have a directive that does that? Maybe you would need that same functionality in other components. Whenever you feel that you have like repeating methods in different components with the same name, the same body, and they primarily work to do something in the template, then you can think, oh, you know, maybe I can instruct this to a directive and find a way to apply it to the elements that I need. It would be way more descriptive than... Copp pasting that for all the, all PDs doesn't really help there because you can't, you can sort of write a service that does that, but it won't feel very natural. We don't really think of services as like things that work with the templates. I mean, directly like modify it or do whatever. So yeah, you can do that with the directive. You should do that with the directive. I mean, directive driven development.
Lucas_Paganini:
By the way, since you touched on that point about code reusability, I do have a trick that I use, because I think we talked about this before, but I am a huge proponent of functional programming. It's like a personal preference of mine. But I know that Angular doesn't really push too much on that paradigm. And I think it's OK, because it does make more sense to use object-oriented programming for the mental model that Angular creates. But I find myself sometimes in a situation where I have a component or a directive or a service which just has way too much code in it. It's just way too much. And also, sometimes there are functionalities there that I want to reuse, but it doesn't really make sense for me to isolate in a service or directive just Although I could and it would work, just in terms of mental model, it doesn't really make sense. So what I do in that case is I isolate in a function that creates the function that I want. So for example, I isolate and I have a convention which every function that returns another function, I prefix it with make. So let's say that you have a method that is like, get full name and this is gonna depend on you injecting the user store and then you you inject the user ID anyways like I would have a make get full name and
Armen_Vardanyan:
Yeah.
Lucas_Paganini:
this function is going to take the dependencies required for the the context of the function so for example it would take the and it's going to return a function that takes a user ID and gives you the full name of that user. So that way you can just reuse. In general, I do think it's better if you can isolate things in a directive because that's a more Angular native way of doing this. And also directives are way more powerful nowadays ever since we were able to use them as host directives. So I don't think there's any reason not to isolate things in the directive. We used to have an excuse, which is if I isolate in a directive, I can't apply the directive to my host element unless I am applying from the parent. And sometimes I don't want that. I lose the place where the responsibility is being applied, but we don't really have that anymore. So... But in cases where it doesn't make sense for you to isolate things in a directive or a service or another component, I would definitely recommend the approach that I just talked about. And the cool thing is you can have individual files for all your functions, and you can even like test them way easier. And you don't have to worry about all the angular way of doing testing, which I kind of got used to, but. It is easier when you're just being explicit and giving the function the dependencies that it requires. So if you're just doing regular functions, then it's even easier to test.
Armen_Vardanyan:
makes sense. I enjoy like one of the things that I enjoy in Java X4 is that to test my business logic, I really need to test like casual functions, and even makes me test less functions. So I know that the test cases are covered there. And the component I can just say, imagine you have this data or imagine you have that data and test the template, essentially rather than test that the template is doing whatever I want it to do, okay, rather than focusing then, oh, is this data, how I change this data, or I just can pretend that data is this, if is this this, sounds a bit weird, but during writing that unit test code, it will be just like mark this selector value, check this, expect this. And that really makes more sense than doing it just a purely angular way.
Lucas_Paganini:
Yeah, because you isolate the responsibility, like the responsibility of the components becomes just representing the UI. They lose the responsibility of having
Armen_Vardanyan:
Yeah.
Lucas_Paganini:
to modify it. They just delegate that to somewhere else.
Armen_Vardanyan:
Yeah.
Lucas_Paganini:
Yeah. Cool. Okay. What else can we do with directives, Harman?
Armen_Vardanyan:
This one I like because it feels like a really cool thing that is also useful Like we have this thing that there are lots of things that look cool Not bad, but not really applicable that much or not really solving a real world problem or whatever But this one I liked because it addresses one interesting issue So let's start from the roots of the problem like You have separate components, like you have components that are displayed on each page. For example, the header of the page, the header of your application, the sidebar, I don't know, the footer. Whatever. You have this stuff that is present on almost every page. And you want that stuff, those components, to be in communication with whatever actual pages the user is seeing. So, I don't know, for example, you want to show title there, right? If you go to the home page, it should read home there. If you go to the about page, it should read about and so on. So, there are a couple ways of doing that. You can do it via the router, you can pass some data there and get in the component. But all of them are not really flexible. What if I need something from the state of that component? What if I need to, for example, if I'm visiting someone's profile, I want to see their name in the header. That's how my design works. I want to see their name in the header. So another approach would be to have state management and have that data there and show something displayed on that, depending on the route. That's already a bit complicated, not the very favorite approach of mine, but it has one glaring problem. What if you want like custom content? in terms of like you want specific template for this page and on another place we want somewhat different template and not just you know pure strings displayed as text. What if you want a drop down to be visible on the header if you're in one page? That's a UX thing. Maybe you have a big cluttered page and there is no way that you can declutter it further. So I want to push some more mixed functionality into the header for example. And you want it to look this way. So now you are facing a situation where you're starting to write a big NG switch statement in the header that really does lots of stuff that is not related to I don't know whatever header is supposed to do now. We are doing the drop-downs in the header. What does that mean? And you can't do content projection because you don't call the header in your component. You could do that You could make it in a way that you need to kind of show the header inside every page, use it in the template. But that further complicates things. Now you have to show that header even in the pages that don't have custom content for it. And you might have like 100 pages and 15 of them need custom content and 85 of them really don't need it. and now you are stuck with constantly calling the header component and so on and it could be problematic. So now imagine if you could sort of teleport a piece of your template in one component into another component and when I say a piece of template I really mean that piece of template with all its data, with all its bindings and just transport it somewhere else and show it there. So, turn out you can actually do that. In the example of this article, I'm using Angular CDK and I'm using portals. It makes some of the stuff more easy to implement and it also probably fixes some bugs that we would encounter without it. But I don't want to complicate this podcast with explaining now what the portals are and how they work, we essentially can do that with just ngTemplate. So what we need is one empty element, template element, with an ngTemplate outlet. We need a structural directive that takes a template, the template ref, and we need a service some template refs from one directive and passes it to another component that displays it in that template outlet. That's what is happening here. It sounds a bit complicated, but it's actually like all of those stuff together is like 40 lines of code or something. Essentially, the service is the easy part. You keep one subject and you send template refs in that subject. So you can write like optional methods, like send template and get template somewhere, right? Then you write a structural directive that does exactly that. It takes the template ref and afters you need in that lifecycle, we just use the service to send the template ref, okay? And in the target components, like in our example, we have some pages. we have this service and we have the header component. So what I do in the header component, I just inject the service, I get the template that I want, I give names there. So for example, I have a header template, right? I take the template from the header, using my method on the service. Now I have the template ref from another component in this component. So now what is just left is to pass that template ref to an ngTemplateOutlet. And that's it, it will just render the content template from another component here. And in the page from which I, for example, want to send some template to the header, I will just write, in the example, I called the structural directive portal. So I will just write portal equals, I don't know, header. If I wanted to display in the footer, I will do the same thing in the footer. I will just select the footer named templates. and do, I don't know, on some element, I would do portal equals footer. So now, by that, I mean, you know, display this template in the footer. Of course, there are some nuances you need to destroy that template ref when the parent component, when that instance of directive is destroyed, so you should remove it from the header when you leave this page, for example. I mean, that's more of a business logic thing. Maybe you don't need to destroy it, but I suggest that you in general do that. Destroy the template ref, pass a null, so that the template sort of dies out. And it allows for really cool stuff. Like, it's the most reusable than you can get with a template, okay? There is no top-down relation. There is just, you know, I want this to be displayed there. And that's it, it's very straightforward. It's very understandable. You don't write anything in the component from which you are sending the template, okay? In the pages, you don't write anything. You just write the code, the template you want in the header and drop the directive on it and it just works. In the header component, there is also not much to be done. Like you just select the template you want from the service and pass it to an empty-eng template and that's it. It will just render whatever you send it. The bindings work. So if you want to handle the events there in your component, you just handle them in the usual angular way. Nothing has changed. If you have bindings, if you interpolate something, it all works as if it is inside this component from which you are sending it. And it can get really useful in different scenarios.
Lucas_Paganini:
So the idea is using portals on Angular, but not in the way that people typically think of them. Because when I think of portals, I think model. I think dialogue. I think
Armen_Vardanyan:
Well, that
Lucas_Paganini:
snack
Armen_Vardanyan:
also
Lucas_Paganini:
bar.
Armen_Vardanyan:
works in that scenario.
Lucas_Paganini:
Yeah.
Armen_Vardanyan:
That also works in that scenario. For example, I just thought about it. Like if any of you have worked with PrimeNG, so the way that PrimeNG dialogues work, they also have a dialogue service that opens it and so on. You either need to drop the dialogue component or you need to call the service, but... with this scenario, you can use a portal to dynamically create a dialogue and pass the reference to it. I don't think it's super useful in this case, but yeah, if you have situations when you need to display, I don't know, you have a generic confirmation pop-up, right? There are stuff like this, like, oh, you actually want to delete this or whatever. And in one page, in one specific case, You want some other content to also be there. Well, no problem. Just drop a portal to that confirmation, explicitly define what you want to be shown there. And that's it, you customize this component.
Lucas_Paganini:
Okay, okay, gotcha. But the point that I was going to hammer on most is that although this is a use case, I think this is kind of the use case that mostly comes to people's mind when they learn about portals. But the cool thing about your example, or at least the coolest thing that I can think of is how it makes you realize that portals can be used for... any content that will be projected outside of the normal flow of the component. And that doesn't necessarily mean that it's a model that is going to appear on top of the content. It can also be a content that is in a parent component or in a sibling component somehow, but you want to project from your current component because for some reason, the responsibility of that content is of your component. It's not... from that other component. So that's the case, for example, for a header. The header doesn't have the responsibility of figuring out the title of each page. The component that renders the page is the one that should be responsible for figuring out which title should it be. But the header is responsible for having a place to show the title, and thus you have this mixed set of responsibilities. The place that presents the content is not the place that should be in charge of deciding which content to present. And that's a good scenario where you can use directives to project content there. Pretty cool.
Armen_Vardanyan:
My rule of thumb for that is that you are diving too much into, oh, in this condition, display this, and in this condition, display that, and that is a good use case of maybe delegating it to whatever piece of your app that is actually responsible for that. That is also a way of decoupling your components, actually. In the end, they are interconnected, but you sort of create this layer where they touch each other a bit, but don't really know about each other. The other component just knows that this part will be displayed in a header and nothing else. However, the header works, come on, doesn't care. And the header doesn't know anything about the template that is going to be sent to itself. So yeah, that's a really good way to decouple things if you want reusability.
Lucas_Paganini:
Nice. Now, I understand that we are going to get a teaser. Is that right, Armin? You're going to give us a teaser from an article that you haven't even published yet. So this is kind of an Adventures in Angular exclusive. So we're talking about the next articles that you're going to write for the series, which haven't been published yet, but that you already know what you want to talk about. So. Do you wanna get into that now?
Armen_Vardanyan:
Yeah, why not? This is my most favorite example. That's probably the most favorite directives I had written in my applications. So let's talk about structuring our template. Let's talk about showing content based on conditions and stuff. For example, let's take permissions, right? This is stuff that we want to have in a fairly large applications, like some users can access some pieces of your software and others can't. Maybe something is beyond the paywall or another use case like feature flags. You have this, but it's not ready and you want to sort of cover it before the next version of your app or something, right? So what you in general do in this scenario, like if you have... a store, if you're using ngRx store, then you are one step ahead. And when I say ngRx store, it's just a big fan of ngRx, whatever store that you like. If you have any state management, you are one step ahead because you have the centralized place where to get that data, understand maybe what version of app you're using or what permissions the current user has. So what you would do in general, you would inject the store, select for, I don't know, whatever, specific permission, and then in the template you will write, I don't know, ng-if, if this permission, whatever, display this piece or this component or this template. So it's not bad, obviously. Even without the service, maybe you have something that would call an API and ask if I have the permission to do this. It doesn't really matter how the data getting logic works. What I don't like about this is that first of all the template gets a bit less... I mean, it's understandable that you'd say ng-if and something-something, but if that something has not a very successful name, you need to go to the component, read what exact permission that is, for example, and you need to repeat that stuff with all the components and maybe all the permissions. For example, you select it for, I don't know, can user delete something permission. Okay, and used it. Now you also need can user edit something, can user add something. And then you think, oh, let's just select the permissions and change the template and show the... And write something like permissions.edit, permissions.edit. So you're in this dynamic thing and you don't really like it. What you would really like to is write something like, has permission equals... the name of the permission and that's it. Okay? So how you can do that? Well, you can use the newest Angular features. You can use host directives. Instead of manually doing some, I don't know, calculations and displaying or destroying the template, you can just write structural directive. Let's call it has permission. That's gonna be the example in the upcoming article. And it's gonna receive the name of the permission. And other than that it will just add ng-if as a host directive Subscribe to your whatever stream of permissions or make an API call or whatever However, you determine if the user has permission to do that or a feature flag or whatever And just pass that Boolean that you eventually get a Boolean you're either true or false just pass it to the Hosted ng-if reference. That's it The essentials to use the ngif. You just edit using the host directive feature, the newest feature in directive, and it works. It's so you don't need to do anything. It's super flexible. You can add more inputs. If you give it the name of the permission, but you also have one other concern, like if the user has this permission and also something else, well, you can just add another input, a suffix, maybe, and, and then in the template, you can just do, for example, a has permission, edit, then semicolon, and two dots, whatever condition you want. You can also do an else case and pass it to ng-if-else and pass the template. So it still will work like ng-if, but you will simplify your component code, like the class that you have written. the component, it will get simpler, it will not select for a data that it can sort of pass on. And yeah, this is a super good use case because it's a very real life use case, like what application doesn't have these sorts of repeating checkings. There's also an inverse of this. Imagine you have controls that are essentially the same everywhere. in the sense that, for example, you have a drop-down that displays, I don't know, countries, or you have some inputs that have the same text or whatever, or populated with the same data. So you either will have to select that data in a way in your component and pass it to that other component that you are using. For example, you are using, I don't know, material drop-down. now you have to be straight. And now you are sort of stuck with coptesting this logic if you have this in other places too, or you can write a component that wraps around, I don't know, the same material, drop down, material select, or it's good. That's also not a good approach because now you're encapsulating it further. You now have another layer and you need to think about inputs and outputs of this component. And if that component is, I don't know, is a control value accessor, right? So you can use ngModel. So now your component that wraps around it also needs to be a control value accessor. And I don't know, that's kind of lots of work. Lots of work for something that's not really that hard of a concept. Instead, you can just write a directive, not even a structural directive. You're not doing anything structural. product directive that gets that list of countries and passes it to this other component. That's it. You make this component richer by just dropping it. You say, you know, this is a country's component. Dropdown, for example. Or this is a specific time range, calendar, whatever, so you sort of work around with other people's stuff without needing to either wrap them or bring this functionality to the component. You don't need that, you can just solve the directive and that's it.
Lucas_Paganini:
And even with the reusability aside, you also get simpler code because you don't have everything in a single place. So you can
Armen_Vardanyan:
Yeah,
Lucas_Paganini:
break the responsibility into multiple parts,
Armen_Vardanyan:
it saves a lot
Lucas_Paganini:
which
Armen_Vardanyan:
of time.
Lucas_Paganini:
is easier to read. Yeah. Cool. Okay. I like that one. I think that one is really reusable for whole code bases. because you either have checks for permission or you have checks for feature flags or you have checks for a hundred other different things. So that's definitely something that there should be a library for that. There should be a library that you just import all those things because they are useful for every single project. So I'm pretty sure that something like this exists. We just probably haven't stumbled
Armen_Vardanyan:
And the
Lucas_Paganini:
upon
Armen_Vardanyan:
problem
Lucas_Paganini:
it.
Armen_Vardanyan:
with that is that we talk a lot about business logic in directives. And it's absolutely okay to put business logic in it. It's not only okay. I literally encourage people, please put business logic in directives. It's 100% okay and it's going to make your life way easier. But when you put business logic in a directive, it's not really reusable in another project. The idea is reusable, but the business logic itself is different. And, you know... We still don't have content projection for business logic. I mean, we could do that with, I can write that sort of the generic, uh, permissions directive. I can imagine like I write a function that returns an observable of a boolean for a specific directive and then provide it in the root. Like I will give a function that will allow the user, uh, the developer who uses this directive to provide some logic at the root level. I actually have done something with the very first article in the series, which we talked about that. The password meter thing, it had an input that would allow you to check the user to provide a function that they will use to check for the password strength. So for example, one application thinks that, you know, if the password has 10 symbols, then okay, it's strong. the other one might have different requirements, so you can just pass a function. But if you don't want to go around copy-pasting that function and passing it around, you can just provide it in the root level. You can provide that function and the directory will inject it and find if you have provided one, it will find it and it will use that one instead of the default one. So you can do that sort of stuff too. If there is a business logic piece, you can make it in a way that the user will have to provide that function that will... you can write a factory and as you said, make, I don't know, permission checker, right? It will get the name of the permission, it will return this specific function for checking that. And then you will have a directive that is reusable everywhere, okay? It could be useful, but... Until it's a concern, different apps have really different logic for that sort of stuff. But I think something reusable can be done for feature flags. Feature flags, in general, aren't really business logic. So I don't know. Maybe we can try creating something like that and use feature flags in the brain Angular.
Lucas_Paganini:
Yeah, that makes a lot of sense. All right. Again, that's not even the end, right, Armen? Because I heard that even after that sixth article, you're still gonna do others. Do you already know what you're gonna talk about in the next articles?
Armen_Vardanyan:
I think the last one, I think the seventh is gonna be the last because I got bored with directives. I think I will, they can still find use cases, but these six articles are already pretty big. The last one I will focus on selectors and it will be a general guide like when to use which sort of selectors and what abilities selectors have and also what shortcomings they have. You can't use any CSS selector with a directive. and that's important to keep in mind. So the last article will be sort of a wrap up and it will focus on you can do this, this, this, with directive selectors and you cannot do this, this and that. So yeah, we're gonna have probably seven articles. Yeah.
Lucas_Paganini:
Nice. That's actually a question that we had in the last episode, the limitations of directive selectors. So it's really cool that you're gonna tackle this at the end of
Armen_Vardanyan:
You
Lucas_Paganini:
this
Armen_Vardanyan:
asked
Lucas_Paganini:
series.
Armen_Vardanyan:
that question, so I went on and did some research. So yeah, there are some limitations. Some a bit nasty limitations. I will, I don't remember, I have them written down somewhere when I come around to writing that article. It will be there.
Lucas_Paganini:
Okay, we can, you don't have to say them especially because now everyone has a reason to go read your series. So if you're curious, then you should follow Armin, follow his content, follow him on all his social media platforms so that you are aware of when he launches the last article of the directive series. So. Yeah, Anarmen, do you want to say anything before we start wrapping up this episode?
Armen_Vardanyan:
No, I don't think so. We did a pretty good roundup of what we had. So yeah, feel free to read my articles. Feel free to comment them if you have interesting use cases. I'm always open to learning more. So yeah, that's it for me, I think.
Lucas_Paganini:
Awesome. OK. So let's go into promos and then picks. So I'm going to start with promos. It's going to be the same as last week. So I am going to promote my company, Envoyed. We are specialized in Angular development. So we can either create an entire project from scratch, and then in this case, maybe you or the client that is hiring us that doesn't even care about Angular, which is super fine too, but in case there's an already existing project and this project happens to be Angular-based, then we can definitely help either with fully outsourcing the project to us and we're handling the entire project. But also, that's not the case for most companies. Most companies, they don't want to outsource the entire thing. They just want help. They just need more people because it's so hard to find excellent professionals and onboard them on the project. And honestly, sometimes the company doesn't need the person for so long. So are they going to hire somebody just to fire them a couple months afterward? That's terrible. So they get into this position where they know that they need more help right now, but they also know that they might not need that help after a couple of months. So they get stuck into not hiring anyone to help during this period. So if you or your company finds itself in that position, then you can contact us on unvoid.com and we can either help you with a staff augmentation. So putting my team to help your team in your current project in a flexible way with non-fidelity contracts. So you and your company can cancel at any moment in time if you don't like my voice or the work that we've been doing. So you can just cancel. And... Or if you want to just delegate an entire project, you can do that too. That's fine. Either way, we can help if it's an Angular-based project. So unvoid.com if you're looking for that. And if you have somebody to refer to Unvoid, so perhaps you are not looking for the service, but you know somebody that could be interested in what we offer, then you can go to unvoid.com slash refer. hyphen clients the link is gonna be in the show notes and by referring somebody you can get paid up to 10,000 US dollars for each client that hires us based on your referral. So that's shit ton of money so you can go to this link and See how that works. It's a very very easy process and yeah, that's gonna be my promotion today. How about you Armin? anything you would like to promote.
Armen_Vardanyan:
I don't think I have anything to promote at this point but hopefully soon I will have the wedding on it.
Lucas_Paganini:
Okay, every time you say that, I get more and more curious.
Armen_Vardanyan:
Well,
Lucas_Paganini:
So
Armen_Vardanyan:
I
Lucas_Paganini:
I
Armen_Vardanyan:
tried
Lucas_Paganini:
can't wait
Armen_Vardanyan:
not
Lucas_Paganini:
for
Armen_Vardanyan:
to
Lucas_Paganini:
the day.
Armen_Vardanyan:
get out of the curve.
Lucas_Paganini:
Alright, so in terms of picks, I am going to pick a TV series that I love. I have watched every episode launched thus far, but my girlfriend just started out watching this series and now I'm rewatching everything again and realizing how good it is right from the start. Jesus, how can it be so good in every single episode? And it is Peaky Blinders, it's already a pretty famous TV show, but if you were just waiting for another push to watch this show, then that's it. Imagine me pushing you towards the television. Go watch it, it's on Netflix, it's an amazing series. How about you, Armin?
Armen_Vardanyan:
I'm gonna talk about something from Netflix too. I really enjoyed watching the Our Planet documentaries. It's a series about different bios, biomes on Earth. There is the freshwater, there is jungle, there is forest, there is something about Antarctica. It talks about animals, it talks about climate change and of course I really can't pass on a documentary where David Attenborough is talking like this man's voice is so captivating I can literally listen to him for hours and they are very beautifully shot so super relaxing but also like informative you learn a lot of stuff about animals and and general biodiversity of earth so I would recommend giving it a watch if you like nature. It's super interesting and really well shot. So yeah, that's good. The Our Planet documentary is going to be my pick this week.
Lucas_Paganini:
Awesome, okay. So, Arman, again, thank you so much. It's always a pleasure to have you on the show. Thank you for all the knowledge that you brought to the episode today. And I hope to see you in the next episode.
Armen_Vardanyan:
Thank you too, thanks a lot for having me, always a pleasure talking on Ventures in Angular.
Lucas_Paganini:
All right, bye guys, see you next week.