Angular2 Quicky - Local template variables

Angular2 Quicky - Local template variables

Local template variables in angular2 can be used to easily reference HTML elements and use their properties either on sibling or child nodes.

It's pretty easy to create and use those local template variables. Let's say you've an input file for dealing the firstname of someone.

<input type="text" placeholder="your name please" required maxlength="25" />  

You can make the HTMLInputField available to sibling or child nodes using the # symbol.

<input type="text" #firstName placeholder="your name please" required />  

Now let's say we want to extend our small example to provide a char counter besides the element, so users can see how many chars are left for the value. First let's add the corresponding span which is responsible for displaying this information.

<input type="text" #firstName placeholder="your name please" maxlength="25" required />  
<span><small>{{firstName.value.length}} / {{firstName.maxlength}} </small></span>  

But that's not enough, if you execute the sample at this point you will see something like this

0 / 25

See the 0 / 25 right after the textbox. Its displaying the maxlength but and it's not updating the actual length property of the value (0 in this case). To fix that you can either hook up a function from your component, or you can just use a small trick to let angular update the view as soon as user does a keystroke. Update the sample above to look like the following.

<!-- line breaks to make code more readable -->  
<input type="text"  
       #firstName 
       placeholder="your name please" 
       maxlength="25" 
       (keyup)="0" 
       required />

<span><small>{{firstName.value.length}} / {{firstName.maxlength}} </small></span>  

If you follow the instructions the sample should behave like the following

Passing data to a component's function

In the sample above, I'm using an simple app component with no logic

export class AppComponent{  
}

let's extend the class to provide some super logic

export class AppComponent{  
   repeatedName: string = null;

   repeatName(name: string, times: number){
     this.repeatedName = (new Array(times+1)).join(name + " ");
   }
}

The repeatName method will print the value of name as many times as provided for the times parameter.

Let's reuse the things we've learned during this article and update the template to look like the following

<input type="text"  
       #firstName 
       placeholder="your name please" 
       maxlength="25" 
       (keyup)="0" 
       required />

<span>  
  <small>{{firstName.value.length}} / {{firstName.maxlength}} </small>
</span>  
<br/>  
<label>repeat </label>  
<input  
   type="number" 
   min="1" max="999" 
   #repeater 
   (keyup)="repeatName(firstName.value, repeater.value) />
<label> times</label>  
<p>{{repeatedName}}</p>  

If you execute the sample and enter for example John and set the value of the repeater to any valid integer you will see 31 if you provide 3 as repeater count.

So why is that? As you may guess, HTMLInputField is treating the value as a string. ng2 will forward the value as string no matter how your method signature looks like.

To fix this, update the repeatName method to look like shown below

repeatName(name:string, times:string){  
  if(times){
    let repeat = parseInt(times) + 1;
    this.repeatedName = (new Array(repeat)).join(name+ " ");
  }
}

Now the sample will work as expected and multiply the name depending on the number your provide.

Happy coding

Comments

comments powered by Disqus