0

I am having a hard time understanding this type of error in angular: (TS) Element implicitly has an 'any' type because of Expression of type 'setAttribute' can't be used to index type EventTarget. Property 'setAttribute' does not exist on type EventTarget.

I'm working on a project where I have an SVG map and it is interactive. I mouse over a country and it pulls the data about that country from the api. A snippet is below. But I am getting compilations error on the e.target["setAttribute"]("fill", "red") from the map-image.component.ts. I don't understand what am I doing wrong and can't find what that error means.

I then changed the e to any:

    pieces.forEach((e: any) => {

      e.addEventListener("mouseenter", e =>

        e.target["setAttribute"]("fill", "red")

      );

and compilation error is fixed, but no data is being pulled from the api.

map-service.ts:

  getCountry(countryCode: string) {

    return this

      .http

      .get("https://api.worldbank.org/v2/country/" + countryCode + "?format=json");

  }

map-image.component.ts:

export class MapImageComponent implements AfterViewInit {

   @Output() onSelection: EventEmitter<any> = new EventEmitter();



  ngAfterViewInit() {

    let pieces = Array.from(document.querySelectorAll("path"));



    pieces.forEach(e => {

      e.addEventListener("mouseenter", e =>

        e.target["setAttribute"]("fill", "red")

      );

map.component.ts:

  loadCountryData(e: any) {

      this.country.name = e.name;



      this.mapService

        .getCountry(e.countryCode)

        .pipe(take(1))

        .subscribe((response: any) => {

          this.country.data = [

            "Name: " + response[1][0].name,

            "Capital: " + response[1][0].capitalCity,

            "Region: " + response[1][0].region.value,

            "Income Level: " + response[1][0].incomeLevel.value

          ];

        });

  }

map.component.html:

<div class="row columns">

  <div class="col pr-5">

    <app-map-image (onSelection)="loadCountryData($event)"></app-map-image>

  </div>



    <div class="col-4">

      <div class="card">

        <div class="card-body">

          <h5 class="card-title">{{ country?.name }}</h5>

          <div class="card-text">

            <ul>

              <li *ngFor="let o of country?.data || []">

                {{ o }}

              </li>

            </ul>

          </div>

        </div>

      </div>

    </div>

  </div>
3
  • You probably have noImplicitAny set to true in your .tsconfig Commented Jul 28, 2021 at 12:18
  • I can't see any path element in your html. Are you sure you get any objects? Commented Jul 28, 2021 at 12:19
  • 1
    Just as a warning, direct DOM manipulation is very much an anti-pattern in Angular. This is most certainly not the way to achieve the behaviour you want. Commented Jul 28, 2021 at 12:22

1 Answer 1

1

You need to tell the compiler what e.target actually is:

e.addEventListener("mouseenter", (event: MouseEvent) =>
  (event.target as HTMLElement).setAttribute("fill", "red");
);

Also you're shadowing the e variable which isn't great for readability, so I renamed it to event.

I also don't know what your e element actually is so I just put HTMLElement as the type. If you're using something like a div for example you can change it do HTMLDivElement, or any type corresponding to the element you have. It's fine to leave it as is however as adding a more specific type in this scenario won't do anything.

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

Comments

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.