I have this Javascript class where in construct I initialize some class variable and I bind a click event and I try to get the declared variable if the click method is called, but returns every time undefined
class Tabs {
constructor() {
this.tabLinks = document.querySelectorAll('[data-tab]')
let self = this
if( this.tabLinks.length > 0 ) {
this.tabContainer = document.querySelectorAll('[data-target]')
this.tabLinks.forEach((el) => {
el.addEventListener("click", self.setActiveTab, false);
} )
}
return
}
setActiveTab(e) {
e.preventDefault()
let currentEl = e.target
console.log(currentEl)
console.log(this.tabLinks) // Is undefined
Tabs.tabLinks.forEach((el) => {
el.classList.remove("is-active")
} )
}
}
export default Tabs
what I do wrong in this case?
Related
We developed a Vue custom directive that replaces DOM elements with a comment depending if the user has permission for specific information. This directive works fine when we use it in any DOM element, but when we apply it to another Vue component it doesn't work as expected because the mounted() function gets called, which we don't want
The problem really is that we don't want to render that component, specifically if it has an API call because this makes the whole system fail.
Here is the directive code:
Vue.directive("checkPermission", {
bind: (el, binded, vnode) => {
let permissions = self.$nuxt.$store.$auth.user.permissions;
if (
!self.$nuxt.$store.$auth.user.isAdmin &&
permissions &&
permissions.length > 0
) {
let hasPermission = false;
const { action, subject } = binded.value;
hasPermission = permissions.some(
permmission =>
permmission.action === action &&
(Array.isArray(subject) ? subject.includes(permmission.subject) : permmission.subject === subject)
);
if (!hasPermission) {
const comment = document.createComment(" ");
Object.defineProperty(comment, "setAttribute", {
value: () => undefined
});
vnode.text = " ";
vnode.elm = comment;
vnode.isComment = true;
vnode.context = undefined;
vnode.tag = undefined;
vnode.data.directives = undefined;
vnode.children = undefined
if (vnode.componentInstance) {
vnode.componentInstance.$el = comment;
}
if (el.parentNode) {
el.parentNode.replaceChild(comment, el);
}
}
}
},
I am implementing a scenario in which on clicking outside the drawer, i want to execute the saveChange action but somehow it is giving me the error that saveChange is not a function. I tried different ways to set the context but it is not working.
export default class DrawerModel {
constructor(context) {
this.data = context.primaryInfoData;
this.name = ko.observable('test');
document.addEventListener("click", function (e) {
var self= this;
var element = e.target;
let isOutside = true;
for (var element = e.target; element; element = element.parentNode) {
if (element.id === 'drawer_primaryInfoDrawer') {
isOutside = false;
}
}
if(isOutside) {
self.saveChanges();
}
});
}
saveChanges() {
const data = {
title: this.name(),
}
this.data.valueChangeHandler(data);
};
}
Error :
Uncaught TypeError: self.saveChanges is not a function
this is because in your event listener, this refers to the window instead of your class. you can fix this by adding .bind(this) to your function like so:
document.addEventListener("click", function (e) {
// ...
}.bind(this));
I have class with variables, I want change variable value by another function in external file
Class code
frappe.ui.Notifications = class Notifications {
constructor() {
frappe.model
.with_doc('Notification Settings', frappe.session.user)
.then(doc => {
this.notifications_settings = doc;
this.make();
});
}
make() {
this.$dropdown = $('.navbar').find('.dropdown-notifications');
this.$dropdown_list = this.$dropdown.find('.notifications-list');
this.$notification_indicator = this.$dropdown.find('.notifications-indicator');
}
};
i wand change variable this.$dropdown
frappe.ui.Notifications.$dropdown = $('.Header').find('.dropdown-item-notifications');
The Notification class instance is set at frappe.frappe_toolbar.notifications. You can use it to override the property.
frappe.frappe_toolbar.notifications.$dropdown = $('.Header').find('.dropdown-item-notifications');
I am creating a Class instance, I am kinda stuck on variable reassign, like below
class A {
constructor() {
this.checkBoolen = false
}
checkBoolen = false // error, asks to install #babel/plugin-proposal-class-properties to get support.
click() {
document.addEventListener('click', e => {
this.checkBoolen=true // <- a class constructor's prototype property can't be reassigned.
})
}
doSomthing() {
if(this.checkBoolen = true // <- never get there) {
console.log('do something')
setTimeout(function(){ this.checkBoolen = false}, 3000)
}
}
}
Looks like either I need to use #babel/plugin-proposal-class-properties? or change the Class to a function? I am wondering if there is a way to change variable inside Class or it is a bad practice?
There are multiple mismatch brackets, class keyword is uppercased
class A {
constructor() {
this.checkBoolen = false
}
checkBoolen = false // error, asks to install #babel/plugin-proposal-class-properties to get support.
click() {
document.addEventListener('click', e => {
this.checkBoolen=true // <- a class constructor's prototype property can't be reassigned.
});
}
doSomthing() {
if(this.checkBoolen = true )// <- never get there) {
console.log('do something')
}
}
And you can use it like this
let obj = new A();
obj.checkBoolen=true
obj.doSomthing()
I would not make my structure like this, but perhaps you should take a look.
class WTF{
constructor(clickElement){
this.clickElement = clickElement; this.checkBool = false;
clickElement.onclick = e => {
this.click();
console.log(this.checkBool);
}
}
click(){
this.checkBool = !this.checkBool;
return this;
}
}
let wtf = new WTF(document);
Just keep clicking on the page.
you have typeo
1- start class with lowercase class
2- check eventlistener syntax
class D {
constructor() {
this.checkBoolen = false;
}
checkBoolen = false // error, asks to install #babel/plugin-proposal-class-properties to get support.
click() {
document.addEventListener('click', (e) => {
this.checkBoolen=true; // <- a class constructor's prototype property can't be reassigned.
});
}
doSomthing() {
if(this.checkBoolen = true ) {
console.log('do something');
}
}
}
I have a subclass that does some validation stuff that calls a method in the parent class that extends it, this is working in all places except when I need to access the local scope in the parent class, see example below
subclass
export default class ElementEvent extends Core {
constructor(events){
super(events);
this.validation = this.validateEvent();
this.element = this.getElement();
this.triggered = false;
this.player = false;
this.waitForElementDelay = 3000;
if (this.validation){
if (this.element){
this.processEvent();
} else {
this.waitForElement();
}
}
waitForElement(){
const interval = setInterval(()=>{
const el = this.getElement();
if (el){
this.element = el;
this.processEvent();
clearInterval(interval);
}
}, this.waitForElementDelay)
}
}
parent
export default class Reading extends ElementEvent {
constructor(event) {
super(event);
this.readingZoneHeight = 50;
this.wordsPerMinute = 300;
this.timer = 0;
}
processEvent() {
//this.elementEntryPoint = this.getElementEntryPoint();
//this.elementExitPoint = this.getElementExitPoint();
console.log(this);
console.log(this.readingZoneHeight);
window.addEventListener('scroll', () => {
console.log('Inside Event Listener ' + this.readingZoneHeight);
//this.handleWindowScroll();
});
}
}
When I console log this is shows a Reading class with all the props it should readingZoneHeight, wordsPerMinute etc but this.readingZoneHeight is undefined, however inside the event listener this.readingHeight is the correct value so not sure whats happening here?
Anyone Help?
That happens because you are calling the Reading's processEvent method from the constructor of the ElementEvent. So this is actually called as part of the super(event) call in the constructor of the Reading class.
And since the super(event) happens before you actually assign anything to the this.readingZoneHeight it is undefined at the time you log it.