1

I'm trying to create a clone of a div Element with the method cloneNode and then I want to set the id of the clone with the setAttribute method, but I get this error:

Property 'setAttribute' does not exist on type 'Node'.

enter image description here

Here is my HTML:

<div id="containerParentId" class="row boundary">

<div class="col no-padding" id="containerId" 
(drop)="onDrop($event)" 
(dragover)="onDragOver($event)" 
(dragleave)="onLeave($event)">

    <div class="vl" id="verticalLine" ></div>

    <div id="divTable" class="tableOnePosition"
    draggable="true"
    (dragstart)="onDragStart($event)"
    (drag)="onDrag($event)"
    (dragend)="onDragEnd($event)"

    ></div>
</div>

And here is the js code:

let clone = document.getElementById('divTable').cloneNode(true);

clone.setAttribute('id','newId');

I'm using Angular as my frontend framework.

I have read different questions about this and it should be possible as far as I can see. An example is this question: Is it possible to clone html element objects in JavaScript / JQuery?

Christian
  • 75
  • 1
  • 6
  • [`.cloneNode()`](https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode) returns a [`Node`](https://developer.mozilla.org/en-US/docs/Web/API/Node). [`.setAttribute()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute) is a method of [`Element`](https://developer.mozilla.org/en-US/docs/Web/API/Element). And that's what TypeScript is trying to tell you. – Andreas Mar 07 '20 at 12:47
  • What would be the best solution to fix the problem then? – Christian Mar 07 '20 at 15:28

1 Answers1

3

.cloneNode() returns a Node but .setAttribute() is only available on Elements (or derived types of it). And that's what TypeScript tells you with the warning/error.

You have to tell TypeScript that the node returned by .cloneNode() is actually a Element/HTMLElement/HTMLDivElement. To do so TypeScript knows the concept of Type assertions (which is like a type cast in other languages).

There are two forms to specify a type:

  1. < Type > -> const d = <HTMLDivElement> document.querySelector("div")
  2. as -> const d = document.querySelector("div") as HTMLDivElement

Your script would then look like:

const clone = <HTMLDivElement> document.getElementById('divTable').cloneNode(true);

or

const clone = document.getElementById('divTable').cloneNode(true) as HTMLDivElement;

Example in the TypeScript Playground

Andreas
  • 21,535
  • 7
  • 47
  • 56