How to declare ClassName.FunctionName.myFunction() in JavaScript? - javascript

So, I'm trying to access the two functions within the function within a Class. modal_1() as shown below in the code. The console.log("inside 1st"); works fine, but when im trying to go further ( e.g. modal_1.show_modal_1(); ) it gives me the following error message:
Modals Class:
const Modals = class {
modal_1(){
console.log("inside 1st");
var hide_modal_1 = function () {
console.log("hide modal 1");
//document.getElementById("modal_setup3DScene").style.display = "none";
};
var show_modal_1 = function() {
console.log("show modal 1");
//document.getElementById("modal_1-content").style.display = "block";
};
}
};
What I use to call the Modals Class:
let modals_List;
function setup() {
modals_List = new Modals();
modals_List.modal_1().show_modal_1();
}

You do not explicitly return something inside the function modal_1, so the return value will be undefined. Then you are trying to call show_modal_1() on undefined. Because that property does not exist on it, you get this error.
You can solve it by returning the functions as follows:
const Modals = class {
modal_1() {
console.log("inside 1st");
return {
hide_modal_1: functio () {
console.log("hide modal 1");
},
show_modal_1: function() {
console.log("show modal 1");
}
}
}
};

Related

Button is self-pushing (JS)

Logout button class, Im creating instance to connect it with API. After the moment instance created it is immediately activated like the button was pushed
Can you help to understand what is wrong?
I'm just beginner
class LogoutButton {
constructor() {
[this.logoutBtn] = document.getElementsByClassName('logout');
this.action = (f) => f;
this.logoutBtn.addEventListener('click', this.logoutClick.bind(this));
}
logoutClick(event) {
event.preventDefault();
this.action();
}
}
instance
"use strict"
let newLogoutButton = new LogoutButton();
const logoutSuccess = (data) => {
if (data.success === true) {
location.reload();
} else {
alert("");
}
};
newLogoutButton.action = ApiConnector.logout(logoutSuccess);
the issue is with the last line
newLogoutButton.action = ApiConnector.logout(logoutSuccess);
change it to
newLogoutButton.action = () => ApiConnector.logout(logoutSuccess);
The last line needs to be a function, right now you're just immediately calling .logout()
newLogoutButton.action = () => ApiConnector.logout(logoutSuccess);

Calling a function to apply discounts before submitting the form in VUE.JS

I need to apply corresponding discounts to each item in my campaign.items before submitting my form with Axios.
For this, I have a function that works correctly:
applyDiscount(price) {
return price - (this.totalDiscount * price)
},
I'm placing the function call inside my submit function before submitting:
methods: {
submit() {
this.campaign.items.forEach(function(item) {
this.applyDiscount(item.price)
}),
var data = new FormData()
I'm getting the error:
Error in v-on handler: "TypeError: Cannot read properties of undefined (reading 'applyDiscount')"
The issue is that this inside of your anonymous function isn't the same as this outside of it. Typically what you can do is to get a reference to this before, by doing let that = this; and then use that inside of the other function:
class Demo {
applyDiscount() {
console.log('hi');
}
example() {
var that = this;
[1,2].forEach(function() {
that.applyDiscount();
})
}
}
let x = new Demo();
x.example()
or you can bind this:
class Demo {
applyDiscount() {
console.log('hi');
}
example() {
[1,2].forEach((function() {
this.applyDiscount();
}).bind(this))
}
}
let x = new Demo();
x.example()
or you can use an arrow function:
class Demo {
applyDiscount() {
console.log('hi');
}
example() {
[1,2].forEach(() => {
this.applyDiscount();
})
}
}
let x = new Demo();
x.example()
I would have done the same, I suppose the "global" this is not equal to the component this.
An arrow function should work,
methods: {
submit() {
this.campaign.items.forEach((item) => {
this.applyDiscount(item.price)
}),
var data = new FormData()

Unable to define this context in document.eventListener

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));

jQuery off not working as I expected

Resolved!! see the end of the question for the result that I used
I am trying to write a function that can handle my apps paging by routes.
I have a function route() that is called with argument being the route(page) to move to.
route is an object that defines a model that it uses that handles its logic.
This model contains 3 functions
indexAction
- This renders my view and appends it to my page.
bindEvents
- This is where I have placed all of my click events
shutDown
- This is instructions to run when moving to a new page
The router function first runs shutdown on the current page, here I have the $(selector).off() and $(selector).remove()
it then runs the enidexAction and bindEvents function.
My issue now is when I return to this page, all my click functions are running twice, then three times etc... its as if the off() never actually unbind from the anchor.
here is an example of one of my models
var NewPageModel = (function() {
var instance;
var modal = 'null';
function createInstance() {
var object = {
indexAction: indexAction,
shutDown: shutDown,
bindEvents: bindEvents
};
return object;
}
function indexAction (data, callback){
var partials = {};
ViewManager.render('pageName',{context:data}, partials,function(html){
ViewManager.appendUnique('#xxx',html,'uniqueID');
callback();
});
}
/**
* Remove modal
*/
function shutDown(){
this.modal.off();
this.modal.remove();
}
function bindEvents() {
if(this.modal!='null'){
return;
}
this.modal = $(PagerManager.pages.newGroup.id);
this.modal.on('click','div.close', function () {
shutDown();
});
this.modal.on('click', 'button.cancel', function () {
shutDown();
});
this.modal.on('click', 'button.submit', function () {
//code that submits form information
});
}
return {
getInstance: function () {
if (!this.instance) {
this.instance = createInstance();
}
return this.instance;
}
};
})();
EDIT!!
So I am still learning about the importance of scopes and how they can be applied to functions
Here is the working code
var NewPageModel = (function() {
var instance;
var modal;
function createInstance() {
var object = {
indexAction: indexAction,
shutDown: shutDown,
bindEvents: bindEvents
};
return object;
}
function indexAction (data, callback){
var partials = {};
ViewManager.render('pageName',{context:data}, partials,function(html){
ViewManager.appendUnique('#xxx',html,'uniqueID');
callback();
});
}
/**
* Remove modal
*/
function shutDown(){
this.modal.off();
this.modal.remove();
this.modal = null;
}
function bindEvents() {
//This is confused logic, if I use off() in shutdown, I don't need to do this as I need to bind all the events again. hence in shutdown modal=null;
if(!this.modal){
return;
}
this.modal = $('#modal');
this.modal.on('click','div.close', function () {
shutDown().apply(this);
}).bind(this);;
this.modal.on('click', 'button.cancel', function () {
shutDown().apply(this);
}).bind(this);;
this.modal.on('click', 'button.submit', function () {
//here I only use the apply(this) if I use another internal function
//code that submits form information
}).bind(this);;
}
return {
getInstance: function () {
if (!this.instance) {
this.instance = createInstance();
}
return this.instance;
}
};
})();
You are losing your this in the event handler functions (this will be the element clicked) so the shutDown is not getting the correct this:
this.modal.on('click','div.close', function () {
shutDown();
});
should be:
var self = this;
this.modal.on('click', 'button.cancel', function () {
self.shutDown();
});
e.g.
function bindEvents() {
var self = this;
if(this.modal!='null'){ /// <<<< !!!!!! WTF
return;
}
this.modal = $(PagerManager.pages.newGroup.id);
this.modal.on('click','div.close', function () {
self.shutDown();
});
this.modal.on('click', 'button.cancel', function () {
self.shutDown();
});
this.modal.on('click', 'button.submit', function () {
//code that submits form information
});
}
Note: I am ignoring the string comparison to null for now as I have no clue what you are doing there :)
As pointed out in comment by #Gurami Dagundaridze you can also retain the correct this using bind (I think the syntax goes like this):
this.modal.on('click', 'button.cancel', shutDown.bind(this));
In the spirit of keeping your syntax and just fixing the bug,
if(this.modal!='null'){ should be if(modal!='null'){
Because this.modal will be undefined at that condition and will just return.
In the spirit of fixing your code, you need to keep a reference to this or it will default to window in the browser.
var modal;
function createInstance() {
var object = {
modal : modal,
shutDown: shutDown,
bindEvents: bindEvents
};
return object;
}
function bindEvents() {
if(this.modal){
return;
}
// ..... //
this.modal.on('click','div.close', function () {
shutDown.apply(this);
}.bind(this));
// ..... //
}
Working demo :
http://jsfiddle.net/uyovgdj3/

Javascript object accessing it's properties

I am trying to create an object in javascript that has an animation run which calls another method when it finishes.
function panel_manager() {
this.animating = false;
this.doAnimate = function (nPanel) {
//if we're still moving panels, do nothing
if(this.animating) return;
this.animating = true;
//enlarge new panel
$("#panel" + this.focusedPanel).animate({width:"115px"},1000, this.endAnim);
}
this.endAnim = function () { alert("called"); this.animating = false; }
}
A whole lot has been cut for brevity and this code does work when it isn't inside an object and uses global variables. The alert runs, but animating isn't changing.
variables.
function panel_manager() {
var that = this;
this.animating = false;
this.doAnimate = function (nPanel) {
if(this.animating) return;
this.animating = true;
$("#panel" + this.focusedPanel).animate({width:"115px"},1000, that.endAnim);
}
this.endAnim = function () { alert("called"); that.animating = false; }
}
Inside of this.doAnimate add a $.proxy.
var callback = $.proxy( this.endAnim, this );
$("#panel" + this.focusedPanel).animate({width:"115px"},1000, callback);
Basically the problem is you lose your this value when you assign it to a callback like this. proxy will make sure the function is called with the proper this.
Cheers!

Categories