Angular Tutorial: Signal Queries with the viewChild() and contentChild() Functions

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
If you work in Angular and haven’t heard yet,   many things are in the process of switching  away from decorators over to signals. I’ve already shown you how component  or directive inputs have changed   over from the @Input decorator to  signals with the input() function. In this video we’ll take a look at  how we can convert the @ViewChild and   @ContentChild decorators over to signals with  the viewChild() and contentChild() functions. We’ll take an example application  that I previously created   for a video demonstrating how to use the  @ViewChild and @ContentChild decorators,   and we’ll switch them over to the new signal  functions producing the same end result. Ok, let’s get to it! So, here’s the demo application  that I was talking about. It lists out a searchable list of NBA players. We have created three examples. One where we used the @ViewChild decorator and  a template reference variable to select the   HTML input element for our search field  in order to focus it on initialization. Then, we have another example also using the  @ViewChild decorator along with a component   to focus the search form, on initialization,  but when it’s nested within another component. And, for the final example we used  the @ContentChild decorator to focus   the search field when it’s been  included within projected content. And in this video, we’ll convert  each of these over to signals using   the viewChild() and contentChild() functions. Ok, let’s start with the @ViewChild and  template reference variable DOM element example. Ok, here in this example we can  see, in our search component,   we have the @ViewChild decorator that queries for  a template reference variable named “searchField”. And if we switch over to the template, we can  see the variable on our search input here. Ok, let’s switch back to the code. A couple more things to note,   we’ve also made this decorator static  because we know it will always exist. When we do this, it becomes available earlier  in Angular’s component lifecycle events,   so we’re able to set focus  in the ngOnInit() hook here. If it wasn’t static, we’d need to add  it in the ngAfterViewInit() lifecycle   event instead because it wouldn’t be  available until the view is ready. Ok, now that we understand what’s going on  here, let’s switch to the viewChild() function. This function is part of a set of what  are known as “signal queries” in Angular. These queries are used to find child  components, directives, or DOM elements. If we’re searching for something directly within  the component template, then we’re using the view. To contrast, if we’re searching for something   that will be inserted within a  content slot, we’re using content. In this case, since we’re  dealing with the component view,   this function is considered a “view query”. Anything dealing with projected content  would be considered a “content query”. We’ll see an example of  this later on in the video. Ok, to use the viewChild() function, we’ll create  a private variable that we’ll name “searchField” . Since we’re going to replace our existing   “searchField” property it’ll  be named the same for now. We’ll remove the old one once we’re done. Then, we just add the viewChild() function. And we’ll need to type it to  an ElementRef, HTMLElement. Ok, now we can remove the old  variable set with the decorator. And, we can remove the decorator import too. Then, all we need to do is, since  this property is now a signal,   we need to add parenthesis where we’re using it. And that’s it. If we save, we should see that our search field is   focused on initialization just  like it was before the change. And there we go, so that works properly. Now, since this is now a signal,   we can switch this over to use an effect()  instead of the ngOnInit() lifecycle event. This will make it available as soon  as the viewChild() signal is set. To do this, let’s add a constructor(). Within the constructor, let’s  add the effect() function. And within the callback here,  we can move our focus call. Now we can remove our ngOnInit()  function, interface, and import too. Now, we should be able to save and  see this still working correctly. And there we go. Pretty cool. One more thing we can do here is, since  we know that this field will always exist,   we can make it required just like  we can with the input() function. We just add, dot, required. Now, Typescript will infer that  this variable will always exist,   meaning we no longer need the question mark here. Ok, that’s it. If we save again, everything  should work as expected. And it does, cool. Now, this would mean that we’d  get an error if this were to   become conditional or something in the future. So that’s the viewChild() function querying for an   HTML element , now let’s query for a  component within the template instead. Here, in this example, we have moved  the search form to its own component. Then, this search form component gets  included within the parent search component. When we switch back over to the  code for the search form component,   we can see that we have our “searchField”  variable available as a public property so   that it can be accessed externally  by other components or directives. Now, let’s take a look at the  code for the search component. We have an old @ViewChild decorator used to  access the SearchComponent within the view. It’s also static like the previous  example and it’s accessed in the   ngOnInit() lifecycle hook to set focus  of the text field within that component. This example will be very similar to the last one   accept we’ll be using a component for  our query instead of an HTML element. So, let’s add a new private  variable named “searchForm”. Then we’ll use the viewChild() function again. We’ll make it required. Then, we’ll pass it the SearchFormComponent class. And that’s it. Now we can remove the old  property, set with the decorator. We can remove the import for  the @ViewChild decorator. Next, we need to add parenthesis  to the “searchForm” property. Next, we can add a constructor(). Then we can add the effect() function. Now we can move the focus call  into the effect function callback. And last but not least, we can  remove the ngOnInit() function,   the interface, and the import too. And that should be it. Let’s save, and make sure  it’s still working properly. There it is, nice. So now we know how to query for both DOM elements  and components or directives within the view. Up next, let’s look at how we’d  use the contentChild() function   to query for a component within projected content. Ok, in this example, we have our same search form   component, but the parent search  component has changed a little. If we look at the template, we can  see that it has a content slot. So, let’s take a look at the app component  template where this search component is used. Here, we can see that the search form component is  included in the slot for the search component now. So it’s projected content  within the search component. So now to access this search form component from   the parent search component we’ll  be dealing with a content query. Let’s look at the code for the search component. Here we can see that we’re using  the old @ContentChild decorator to   create a static “searchForm” property  querying for the SearchFormComponent. So, this is exactly the same as  the last example accept we’ll   use the contentChild() function in this case. So, let’s create a private  field named “searchForm”. Then we’ll use the contentChild() function. We can make it required here too  since we’ll always want to include it. And then we just pass the  SearchFormComponent class. Now we can remove the old property  set with the @ContentChild decorator. We can remove the decorator import too. Now we can add a constructor. Then we can add the effect function. Then we can move the focus call into the effect. We then need to add parenthesis to  the “searchField” property here. Ok, all that’s left now is to remove the  ngOnInit() function, interface, and import. Cool. Now let’s go ahead and save to make  sure everything is working correctly. Nice, it’s focused just like we want. So, there you have it. Now you know how use the new viewChild()  and contentChild() signal query functions. They’re not too much different than the old  decorators but you’ll probably want to start   using them moving forward to modernize your  Angular applications and now you’ll know how. That’s all for now. Thanks for watching.
Info
Channel: Brian Treese
Views: 546
Rating: undefined out of 5
Keywords: angular, angular tutorial, angular training, frontend web development, javascript, typescript, angular course, angular components, angular directives, angular view child, angular content child, angular signals, signals
Id: b35ts9OinBc
Channel Id: undefined
Length: 10min 47sec (647 seconds)
Published: Fri Apr 19 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.