I am new to prototype model coding in JavaScript.
I am trying to access properties($owl_nav and $owl_dots) of an object(elements) by passing the object to a function(setOverflowWrapperHeight), in code
function setOverflowWrapperHeight(elem) {
var owl_dots_height = elem.$owl_dots.height();
var owl_nav_height = elem.$owl_nav.height();
$('.overflow-wrapper').height(owl_dots_height + owl_nav_height + 150);
}
function NextQ(elements) {
this.checked_input = elements.checked_input;
this.$owl_ques_carousel = elements.$owl_ques_carousel;
this.$owl_nav = elements.$owl_nav;
this.$owl_dots = elements.$owl_dots;
this.init();
}
NextQ.prototype.init = function () {
this.bindEvents();
};
NextQ.prototype.bindEvents = function () {
var _this = this;
this.$owl_ques_carousel.on('click', '.nutrition_assessment_next_quest', function (event) {
_this.$owl_ques_carousel.on('translated.owl.carousel', function (event) {
setOverflowWrapperHeight(elements);
});
});
$(function () {
var $user_meta_div = $('div.user_meta_data_div');
setOverflowWrapperHeight($user_meta_div);
/***** NextQ Object *****/
elements = {
$owl_ques_carousel: $('.owl-carousel#ques-carousel'),
checked_input: true,
$owl_nav: $('.owl-nav'),
$owl_dots: $('.owl-dots')
};
/***** Create instance of NextQ Function *****/
nextQ = new NextQ(elements);
});
But the console outputs this error:
Uncaught TypeError: Cannot read property 'height' of undefined
I want to know if this is even legal. If yes, where am I going wrong?
Related
I'm learning javascript.
I have this code...
var test = new function () {
var vars = {
$hub: null
};
var init = function () {
vars.$hub = $.connection.blabla;
};
return {
vars: vars,
init: init,
$hub: vars.$hub
};
};
$(document).ready(function () {
test.init();
test.vars.$hub..... // Works perfecetly
test.$hub..... // Doesn't work - test.$hub is null
});
I don't get why test.$hub is null when test.vars.$hub isn't null?
Thanks
You should use Object directly with getter on $hub:
var test = new function() {
return {
vars: {
$hub: null
},
init: function () {
this.vars.$hub = 'something';
},
get $hub() {
return this.vars.$hub;
}
}
};
$(document).ready(function () {
console.log(test.$hub) // before init
test.init();
console.log(test.vars.$hub) // Works perfecetly
console.log(test.$hub) // Works too!!!
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
vars (and $hub: null) is defined within the scope of Function test whereas test.$hub is not defined.
If you wrote:
var test = new function () {
var $hub = null;
var vars = {
$hub: null
};
var init = function () {
vars.$hub = $.connection.blabla;
};
return {
vars: vars,
init: init,
$hub: vars.$hub
};
};
You can now access the value of test.$hub as null.
i've a problem with click event on KnockoutJS.
When I click the icon that should call the function to open the pop-up, or rather when I load the page I get the following error
knockout-3.2.0.js:63 Uncaught ReferenceError: Unable to process binding "click: function (){return showOfferDetails }"
Message: showOfferDetails is not defined
i call this function in:
<div title="<spring:message code="frontendResources.Details" />" class="btn-bar btn-details" data-bind="click: showOfferDetails"></div>
The js code of the ViewModel is:
(function(viewModels) {
var viewModel = function(offerID) {
var self = this;
this.pageStates = {
view: 0,
showDetails: 2
};
this.showOfferDetails = ko.observable(null);
this.pageState = ko.observable(this.pageStates.view);
this.offerCredit = ko.observable(null);
this.currentItemToShow = ko.observable(null);
this.hasResults = ko.observable(true);
this.tabViewModel = new TabViewModel();
this.loadData = function () {
backoffice.viewModels.ajaxOverlay.showLoader();
self.showOfferDetails();
};
this.showOfferDetails = function () {
backoffice.viewModels.ajaxOverlay.showLoader();
self.pageState(self.pageStates.showDetails);
backoffice.viewModels.ajaxOverlay.hide();
};
this.hideDetails = function () {
self.currentItemToShow(null);
self.pageState(self.pageStates.view);
}
this.detailsIsVisible = ko.computed({
read: function () {
return self.pageState() == self.pageStates.showDetails;
},
write: function (value) {
if (value) {
self.showOfferDetails();
} else {
self.hideDetails();
}
}
});
this.loadData();
};
viewModels.offerCredit = viewModel;
})( backoffice.viewModels );
What could be the problem?
At viewmodel construction you keep a reference to this in the self variable:
var self = this;
but you're not using this self variable for all of the viewmodel's observables or functions. Instead they are assigned to the possibly changing this reference leading to the "is not defined" error message.
Try setting the observables and functions to the self variable:
self.showOfferDetails = function () {
backoffice.viewModels.ajaxOverlay.showLoader();
self.pageState(self.pageStates.showDetails);
backoffice.viewModels.ajaxOverlay.hide();
};
I have a constructor:
var ProfileDialog = function (containerObj) {
this.init = function () {
this.container = containerObj;
let content = document.createElement('div');
content.innerText = 'Dialog here';
this.container.appendChild(content);
this.container.style.display = 'none';
};
this.init();
};
Then I am extending the prototype of the constructor like this:
ProfileDialog.prototype.open = function () {
this.container.style.display = 'block';
}
var dlg = new ProfileDialog(document.body)
dlg.open();
This works fine, but if I try to put .open() inside an object like this:
ProfileDialog.prototype.actions = {
open: function () {
this.container.style.display = 'block';
}
}
var dlg = new ProfileDialog(document.body)
dlg.actions.open();
It fails with an error
functional.js:25 Uncaught TypeError: Cannot read property 'style' of undefined(…)
because of the wrong context passed to the function.
How do I make sure that independently of the nesting, context would be always the instantiated object?
Can you try binding 'this' to actions.open
Maybe you save this to that before and take it as a closure for the init function.
var ProfileDialog = function (containerObj) {
var that = this;
this.init = function () {
that.container = containerObj;
let content = document.createElement('div');
content.innerText = 'Dialog here';
that.container.appendChild(content);
that.container.style.display = 'none';
};
this.init();
};
As a sample,
I have a object it has the huge no of methods. each method as it own private functions. when i require to refere my object parent, usually i do like this:
var that = this - it works fine.
But in case of huge number is there a way to avoid this?
example:
var x = function () {
return {
init:function () {
this.val = 10;
},
fun1 : function () {
var that = this;
var p = function () {
console.log(this.val) //not works i know
console.log(that.val) //not works
}
},
fun2 : function () {
var that = this;
var p = function () {
console.log(this.val) //not works i know
console.log(that.val) //not works
}
},
fun3 : function () { // it keep grow to 100's..!?
var that = this;
var p = function () {
console.log(this.val) //not works i know
console.log(that.val) //not works
}
}
}
}();
x.init();
Live
I had write a code in js file
(function ($) {
var $r = $.loadaccess;
jQuery.loadaccess.page.user = {
init: function () {
debugger;
var k = 'dd';
alert(k);
}
};
})(jQuery);
var user = jQuery.loadaccess.page.user;
and I am calling it on .aspx page
$(document).ready(function () {
jQuery.loadaccess.page.user.init();
});
but it thrown error for me
"Microsoft JScript runtime error: Unable to get value of the property 'page': object is null or undefined"
on this
jQuery.loadaccess.page.user = {
init: function () {
debugger;
var k = 'dd';
alert(k);
}
};
The error is pretty self descriptive, jQuery.loadaccess is null or undefined. What do you expect jQuery.loadaccess to be? You will need to create this 'namespace' yourself. For example:
jQuery.loadaccess = {
page: {
user: {
init: function () {
debugger;
var k = 'dd';
alert(k);
}
}
}
};
I wouldn't suggest adding objects to the jQuery object though, rather create your own top level namespace.