ko click reference error - javascript

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

Related

Passing object to a function and accessing its properties in JavaScript

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?

jasmine test javascript inner function

Here is my javascript code
function organization() {
var self = this;
function activate() {
// statements
}
}
I know the scope of the method activate() remains inside the method organization() and that is the challenge I am facing.
My requirement is to write a test in Jasmine to ensure method activate have been called.
it('activate method defined?', function() {
expect(activate()).toBeDefined();
});
but this test is failing with the message
TypeError: activate is not a function
Any inputs to make the above test success will be highly helpful.
You don't need to check that private function 'activate' actually called or defined. You need to check that public function 'organization' as I understand is called or defined and if activate set some public properties etc. For example:
function organization() {
var vm = this;
activate();
function activate() {
vm.activated = true;
}
}
it('should activate organization', function() {
organization();
expect(vm.activated).toBe(true);
});
Or if you need, you can make function activate as public:
function organization() {
var vm = this;
vm.isActivated = false;
vm.activate = activate;
function activate() {
vm.isActivated = true;
}
}
it('should activate organization', function() {
vm.activate();
expect(vm.isActivated).toBe(true);
});
Define the script in this way.
function organization() {
var self = this;
self.activate = function() {
// statements
}}
and access the functiion like this
var obj = new organization();
obj.activate();

Error to create namespace in jquery

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.

"create" KO mapping option for nested objects not used when primary "create" is specified

I have the following:
var CardViewModel = function (data) {
ko.mapping.fromJS(data, {}, this);
this.editing = ko.observable(false);
this.edit = function() {
debugger;
this.editing(true);
};
};
var mapping = {
'cards': {
create: function (options) {
debugger; // Doesn't ever reach this point unless I comment out the create method below
return new CardViewModel(options.data);
}
},
create: function(options) {
//customize at the root level.
var innerModel = ko.mapping.fromJS(options.data);
//debugger;
innerModel.cardCount = ko.computed(function () {
//debugger;
return innerModel.cards().length;
});
return innerModel;
}
};
var SetViewModel = ko.mapping.fromJS(setData, mapping);
debugger;
ko.applyBindings(SetViewModel);
When I run this, the 'cards' method never gets hit, so those edit properties in the CardViewModel aren't available. I can hit that debugger if I comment out the "create" method, but I need both. Any idea what's going on?
'cards' is not a valid Javascript variable name. Try something else without the single quotes.
You will also need to edit your CardViewModel code as this in the inner function refers to the inner function and will not see the knockout observable in the outer function.
var CardViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, this);
this.editing = ko.observable(false);
this.edit = function() {
debugger;
self.editing(true);
};
};

Object Not Defined with Knockout Data Mapping Plugin

I'm trying to use the mapping plugin to make children objects' properties observable. I have the following:
// setData defined here
var mapping = {
create: function(options) {
//customize at the root level.
var innerModel = ko.mapping.fromJS(options.data);
innerModel.cardCount = ko.computed(function () {
debugger;
return this.cards().length; // cards not defined - "this" is Window for some reason
});
innerModel.deleteCard = function (card) {
// Pending UI
// call API here
// On success, complete
this.cards.remove(card);
}.bind(this);
innerModel.addCard = function () {
//debugger;
// Pending UI
// Call API here
// On success, complete
this.cards.push(dummyCard);
//this.cardToAdd("");
}.bind(this);
return innerModel;
}
};
var SetViewModel = ko.mapping.fromJS(setData, mapping);
ko.applyBindings(SetViewModel);
When I run this in chrome debugger, I get "Object [Object global] has no method cards". Cards should be an observable array. What am I doing wrong?
innerModel.cardCount = ko.computed(function () {
debugger;
return this.cards().length; // cards not defined - "this" is Window for some reason
});
this is inside the anonymous function you're creating and is therefore bound to the global object. if you want to reference innermodel you'll have to do so directly, or bind innermodel to the function.
innerModel.cardCount = ko.computed(function () {
return innerModel.cards().length;
});
or
var computedFunction = function () {
return this.cards().length;
};
innerModel.cardCount = ko.computed(computedFunction.apply(innerModel));

Categories

Resources