#Element Ref not working

41 messages · Page 1 of 1 (latest)

umbral summit
#

Hi, I just need a bit help in one of my projects where I am using ElementRef but it is not returning.

empty vale
#

You declaring that el in a @ViewChild?

umbral summit
#

nopes

tawdry zephyr
#

Please read #how-to-get-help

neat belfry
#

g!codeblock @umbral summit Show your code, all that is relevant. If you don't know then show all/most/more.

kindred knollBOT
#

@umbral summit, you can use the following snippet to have your code formatted and colored by Discord. Replace ts with the language you need (i.e. html, js, css, etc)
```ts
// your code goes here
```

umbral summit
#
constructor(private el: ElementRef) {

  }
#

@empty vale should I declare it using @ViewChield? If so, how?

tawdry zephyr
empty vale
neat belfry
#

Is this a Directive? Show more code @umbral summit

#

If you don't know then show all/most/more.

umbral summit
#

It is a component

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'rock-paper-scissors';

  constructor(private el: ElementRef) {

  }

  onClickChoiceButton() {
    console.log(this.el.nativeElement);
    this.el.nativeElement = "";
    console.log(this.el.nativeElement);
    console.log("hi");
    console.log(this.choiceButtons);
    console.log(this.btnClose);
    this.choiceButtons.forEach((button: any) => {
      console.log(button);
      const choiceName = button.dataset.choice;
      const choice = CHOICES.find((choice) => choice.name === choiceName);
      this.choose(choice);
    });
    console.log("hello");
  }

  btnRules = document.querySelector('#rules_btn');
  btnClose = this.el.nativeElement.querySelector('#close_btn');
  modalRules = this.el.nativeElement.querySelector('#modal');
  choiceButtons = this.el.nativeElement.querySelectorAll('.choice-btn');
  gameDiv = this.el.nativeElement.querySelector('#game');
  resultsDiv = this.el.nativeElement.querySelector('.results');
  resultDivs = this.el.nativeElement.querySelectorAll('.results_result');
  resultWinner = this.el.nativeElement.querySelector('#results_winner');
  resultText = this.el.nativeElement.querySelector('#results_text');
  playAgainBtn = this.el.nativeElement.querySelector('#play_again');
  scoreNumber = this.el.nativeElement.querySelector('#score_number');
#

This is the code

#

of the ts file

neat belfry
#

Don't do this: this.el.nativeElement = "";

tawdry zephyr
#

Actually, don't do any of what you're doing. Don't access the DOM from a component. Learn how to do things the Angular way.

umbral summit
neat belfry
#

g!toh @umbral summit And I don't know what you are doing... but this is not the Angular Way ™️. Have you built the Tour of Heroes apps from the tutorial in the Angular Guide? They give you an overview of some of what Angular can do and how to do it.

kindred knollBOT
#

@umbral summit The place we recommend starting your Angular journey is with the Tour of Heroes tutorial, located here https://angular.io/tutorial.

neat belfry
#

IMPO you need to do the tutorials in the guide or some other teaching.

#

Why do you have all of these this.el.nativeElement.querySelector?

umbral summit
#

Thank you so much!😊

#

But still to figure out

#

why is it not working?

neat belfry
#

What is the HTML?

umbral summit
#
<div class="container">
    <header class="header">
      <img src="../assets/images/logo.svg" alt="logo" class="logo">
      <div class="score">
        <div class="score_title">Score</div>
        <div class="score_number" id="score_number">0</div>
      </div>
    </header>
    <section class="game" id="game">
      <button class="choice-btn" data-choice="paper" (click)="onClickChoiceButton()">
        <div class="choice paper">
          <img src="../assets/images/icon-paper.svg" alt="paper icon choice">
        </div>
      </button>
      <button class="choice-btn" data-choice="scissors" (click)="onClickChoiceButton()">
        <div class="choice scissors">
          <img src="../assets/images/icon-scissors.svg" alt="scissors icon choice">
        </div>
      </button>
      <button class="choice-btn" data-choice="rock" (click)="onClickChoiceButton()">
        <div class="choice rock">
          <img src="../assets/images/icon-rock.svg" alt="rock icon choice">
        </div>
      </button>
    </section>
#

one section of the html code

tawdry zephyr
#

When the constructor of the component is called, the DOM hasn't been created yet. Components have a lifecycle. You need to learn it, and avoid using the DOM anyway.

neat belfry
#

Quick note src="../assets/images/logo.svg" should be src="/assets/images/logo.svg"
The assets folder is from the root of the app (next to index.html) so an absolute URL (one beginning with a single /) will find it. No need for ../

neat belfry
#

Esp when you could just do something like:

<button class="choice-btn" data-choice="scissors" (click)="onClickChoiceButton('scissors')">
  <span class="choice scissors">
    <img src="../assets/images/icon-scissors.svg" alt="scissors icon choice">
  </span>
</button>

*note: <div> is not allowed inside of <button>

subtle hazel
#

(also id in templates is a bad idea - IDs in the DOM are a global namespace)

neat belfry
#

unless you need to do fragment links to scroll to sections of the page... But yeah seems like you get duplicate IDs all the time once you start adding id= to your template

umbral summit
#

Oh Okayyyy

#

Thank you so much for the help😊

subtle hazel
#

@neat belfry I would prefer <a name="..." to id in that case

neat belfry
tawdry zephyr
#

Unless I miss something, IDs are pretty much unavoidable if you have forms and want to make them accessible: <label for=""> expects an ID. Maybe Angular should have some directive which would generate unique IDs and generate a for attribute based on a template variable, BTW. Something like
<label ngLabelFor="firstName">First name</label><input #firstName>.