2

How do I access the value property of an element in the component in Angular2?

In the Template:

<input #myInput (keyup.enter)="onInput(myInput)"/> 

In the Component code:

import {ElementRef} from '@angular/core';
...
onInput(latLngInputElement: ElementRef) {
  // I want to access the value property of the <input> element here, and
  // modify it so that it is reflected back in the template.

I know that I can pass the myInput.value into the code, but I need the reference so that I can also use the function to update the .value property of the element.

I'd like to know if there is a way to do this that does not involve two way binding to a global variable, because I think it is cleaner to have as few globals as possible. Thanks!

1 Answer 1

2

Angular's solution to this would be two-way binding of the input model to a variable in the component. This wouldn't involve dirtying up the global scope, expecially if you declare the var with a let as per Typescript's docs.

I'd like to know if there is a way to do this that does not involve two way binding to a global variable, because I think it is cleaner to have as few globals as possible. Thanks!

I understand this, but invoking ElementRef might be the worse of two evils here. The Angular docs greatly discourage using it as Angular already does so much to handle the DOM API.

However, you should be able to get the value from latLngInputElement.value.

If you're looking for a cleaner solution:

I would highly recommend checking out Angular's FormBuilder to build a model-driven form as opposed to a template-driven one. It's a very elegant way to control form values on a page programatically instead of on the template. Scotch.io has an excellent blog post on it. It's well worth learning.

Good luck!

Sign up to request clarification or add additional context in comments.

6 Comments

I use ReactiveForms, so I can't use ngModel (throws error, I suppose it doesn't work when using reactive forms), and also I don't want to include one dummy input in any of my formGroup groups. I just need it for the user to type something, but not be part of the programatically created form (but it needs to be among the other, visually, so I can't just put it anywhere). And I also need to be able to set it's value after certain actions.
In my template I have <input type="text" #myInput />. Then, I get the reference using @ViewChild('myInput') inputElement: ElementRef; If I console log this.myInput.nativeElement.value I get the value. But this.myInput.nativeElement.setAttribute('value', 'xxx'); doesn't do anything. Am I doing something wrong? I assume setAttribute is a valid method, since there are no errors on build (and it's there to just pick from the autocomplete list). I've also tried @ViewChild('myInput') inputElement: HTMLInputElement;, there's no value() or setValue() method that can be used.
If you are using the ReactiveFormsModule and have a FormGroup set up, you would assign the input to a FormControl using <input [formControl]="controlName"> You can interact with the field through the FormGroup, i.e formGroupName.controls['controlName'].setValue(value). As arule of thumb, always avoid interacting with the DOM with Angular. The framework does it for you.
I know. But that's what I'm trying to avoid. If that input's data isn't relevant for sending to the server, I think it shouldn't be part of any form group, rather than having to "filter" it out before sending data to the server. I would prefer not to touch the DOM, yes... But how do I tell Angular to "empty" out that input at a time of my choosing, just by having the template reference #myInput?
You wouldn't have to use a template variable, and you wouldn't want to either, as Angular wouldn't call change detection on it. It would likely crash the page. You can clear the value with formGroupName.controls['controlName'].reset(). Either way, you can't clear an input value by setting an attribute on the element. If you don't want it in the FormGroup, take it out of the group and use two-way binding on it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.