Rapid background
According to MDN, popover is an attribute to display a popup in the screen:
The popover global attribute is used to designate an element as a popover element.
Popover elements are hidden via
display: noneuntil opened via an invoking/control element (i.e. a<button>or<input type="button">with apopovertargetattribute) or aHTMLElement.showPopover()call.When open, popover elements will appear above all other elements in the top layer, and won’t be influenced by parent elements’
positionoroverflowstyling.
Still according to MDN, hidePopover() is a method that hide our popover:
The
hidePopover()method of theHTMLElementinterface hides a popover element (i.e. one that has a valid popover attribute) by removing it from the top layer and styling it withdisplay: none.
My implementation
I have a component modal-options that when pressing on a button will call the second component modal-change-password who is defined with the popover attribute to display the pop-up.
<div class="popover">
<!-- skipping not relevant part -->
<div id="pwdDocker" class="rounded">
<button id="updatePwdBtn" popovertarget="updatePwd"><h3>Update password</h3></button>
<app-modal-change-password id="updatePwd" popover [currentUser]="currentUser" (closeModalEvent)="closeChangePasswordModal()"></app-modal-change-password>
</div>
</div>
@Component({
selector: 'app-modal-options',
templateUrl: './modal-options.component.html',
styleUrls: ['./modal-options.component.scss'],
})
export class ModalOptionsComponent implements OnInit {
// skipping not relevant part
closeChangePasswordModal(): void {
const popoverElement = document.getElementById("updatePwd");
if(popoverElement){
popoverElement.hidePopover();
}
}
}
modal-change-password is my popover component, in it we have a button that will close the pop-up by emitting an EventEmitter to the parent.
<div class="alert-box">
<!-- skipping not relevant part -->
<div class="alert-box-action">
<button (click)="save()">Change password</button>
<button (click)="onClose()">Close</button>
</div>
</div>
@Component({
selector: 'app-modal-change-password',
templateUrl: './modal-change-password.component.html',
styleUrls: ['./modal-change-password.component.scss'],
})
export class ModalChangePasswordComponent implements OnInit {
@Output() closeModalEvent = new EventEmitter<void>();
//skipping not relevant part
onClose(): void {
this.closeModalEvent.emit();
}
}
My issue
The typescript compiler will raise me an error stating error TS2339: Property 'hidePopover' does not exist on type 'HTMLElement'. which totally lose me because:
- hidePopover() is a method and not a property
- The method exists and according to MDN, does exist in
HTMLElement
I am still learning a lot everyday about Typescript and so I might be looking in the wrong direction, but I have been researching for a good amount of time now and because of the very recent nature of this attribute, I haven’t found any answers related to my issue.
Why is it raising me an error at the compilation ? How should I update my code to make it work ?
(note: I tried two differents approaches, first with @ViewChild() instead of getElementById() and then with togglePopover() instead just to see if I got an other result, but ended up with the same error for both tries)
>Solution :
hidePopover() is a method and not a property
Method is just a special name for "A property whose value is a function". They are still properties.
The method exists and according to MDN, does exist in HTMLElement
If you look at the browser compatibility section of the documentation you will note that:
- No browser supported it before May this year
- Firefox still doesn’t support it in production (it is locked behind a feature flag).
hidePopover is bleeding edge technology.
TypeScript 5.1 does not support it. TypeScript 5.2 does support it.
Upgrade your version of TypeScript (or consider avoiding it until it has matured a bit more).