150

I'm working with angular4 in my practice work, and this is new for me.

In order to get HTML elements and their values, I used <HTMLInputElement> document.getElementById or <HTMLSelectElement> document.getElementById.

I'm wondering if there is any replacement for this in angular.

Nat Riddle
  • 928
  • 1
  • 10
  • 24
Nino Gutierrez
  • 1,692
  • 2
  • 8
  • 18

5 Answers5

223

You can tag your DOM element using #someTag, then get it with @ViewChild('someTag').

See complete example:

import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';

@Component({
    selector: 'app',
    template: `
        <div #myDiv>Some text</div>
    `,
})
export class AppComponent implements AfterViewInit {
    @ViewChild('myDiv') myDiv: ElementRef;

    ngAfterViewInit() {
        console.log(this.myDiv.nativeElement.innerHTML);
    }
}

console.log will print Some text.

Alexandre Annic
  • 9,942
  • 5
  • 36
  • 50
121

You can just inject the DOCUMENT token into the constructor and use the same functions on it

import { Inject }  from '@angular/core';
import { DOCUMENT } from '@angular/common'; 

@Component({...})
export class AppCmp {
   constructor(@Inject(DOCUMENT) document: Document) {
      document.getElementById('el');
   }
}

Or if the element you want to get is in that component, you can use template references.

Soheil
  • 1,201
  • 2
  • 11
  • 18
Suren Srapyan
  • 66,568
  • 14
  • 114
  • 112
  • 2
    Why should I inject the document object and not use directly that provided by javascript? – Davide Dec 14 '20 at 23:56
  • 3
    @Davide we rely on the system of Angular. Later they can implement very good things and do some checking in their implementation. So we just rely on the abstraction here – Suren Srapyan Dec 15 '20 at 07:11
39

For Angular 8 or posterior @ViewChild have an additional parameter called opts, which have two properties: read and static, read is optional. You can use it like so:

import { ElementRef, ViewChild } from '@angular/core';
// ...
@ViewChild('mydiv', { static: false }) public mydiv: ElementRef;

constructor() {
// ...
<div #mydiv></div>

NOTE: Static: false is not required anymore in Angular 9. (just { static: true } when you are going to use that variable inside ngOnInit)

Gustavo Santamaría
  • 837
  • 1
  • 10
  • 21
  • 1
    It works when you dynamically hide or show elements using `*ngIf`. How are you creating the element? – Gustavo Santamaría Apr 06 '20 at 17:01
  • 2
    Thank you for supplying updated syntax. It's worth noting that you still can't just grab any HTML element by tag name with `@ViewChild('myDiv'...` in Angular 8. You can only grab an element in the component's markup tagged with a template variable, e. g. `#mydiv`. I almost missed that your answer contained the variable tag on the element. – jcairney Jul 29 '21 at 22:05
15

Try this:

TypeScript file code:

(<HTMLInputElement>document.getElementById("name")).value

HTML code:

 <input id="name" type="text" #name /> 
Swati
  • 234
  • 2
  • 10
  • 5
    Please describe what 'name' attribute or value you are referring to with getElementById("name") because it could be either the id or the #name – Joniras Mar 08 '21 at 14:15
10
  element: HTMLElement;

  constructor() {}

  fakeClick(){
    this.element = document.getElementById('ButtonX') as HTMLElement;
    this.element.click();
  }
Cesar Devesa
  • 990
  • 6
  • 14
  • 5
    This is very unsafe (running this command in Angular Universal causes a crash) and should only be used if no other option is possible (also consider that the element may not be present) – Joniras Feb 05 '19 at 17:33
  • 8
    M@Joniras why is it very unsafe? – Sumi Straessle Apr 06 '20 at 18:03
  • Because you are manipulating/accessing directly the native DOM. It is recommended that you access HTML elements using Angular's DOM API (for example ViewChild, Renderer2 or ElementRef), as they are designed to ensure consistency, security, and maintainability. Touching directly the native DOM with document.getElementById bypasses this security and can lead to several issues. Check: https://dev.to/imsabodetocode/dom-manipulations-in-angular-1dh1 – victorperezpiqueras Jun 01 '23 at 09:22