Error : is not a function. How can I fix it? - javascript

This is my lift programm. But I have error.
var person = {
name: "Roman",
position: 2,
goal: 9
};
var lift = {
getPosition : function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
} ()};
console.log("Ok " + person.name + "! You are at " + person.position + " floor");
console.log("Lift is at " + lift.getPosition() + " floor");
Error lift.getPosition is not a function.
How can I fix it??

you code looks broken:
var lift = {
getPosition : function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
} ()};
it seems this should be
var lift = {
getPosition : function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}
};

When you declared getPosition you assigned this property a self invoked anonymous function. (The () at the end, self invokes it)
var lift = {
getPosition: function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}()
};
You can remove them () and call the method like you did "lift.getPosition()":
var lift = {
getPosition: function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}
};
console.log("Lift is at " + lift.getPosition() + " floor");
or leave them and just call the property without the () "lift.getPosition":
var lift = {
getPosition: function() {
var x = Math.floor((Math.random() * 10) + 1);
return x;
}()
};
console.log("Lift is at " + lift.getPosition + " floor");
But that would return the same value every time you use it, because it is only executed once. It really depends on what you are trying to accomplish.

Related

How can I rewrite innerHTML everytime function is called javascript

function he() {
var x = Math.floor((Math.random() * 100) + 1);
document.getElementById("res1").innerHTML = "Heroes have dealt " + x + " damage on villains.";
var vhp = villains - x;
document.getElementById("res2").innerHTML = "<br/>Villains have " + vhp + " hp left.";
vok();
}
function vok() {
var y = Math.floor((Math.random() * 100) + 1);
document.getElementById("res3").innerHTML = "<br/>Villains have dealt " + y + " damage on Heroes.";
var hhp = hero - y;
document.getElementById("res4").innerHTML = "<br/>Heroes have " + hhp + " hp left.";
he();
}
Here is the above code I made function he() is called when a button is clicked and vok function is called after execution of he() function but it's not going good currently i want to overwrite the innerHTML every time the function is runned how am I supposed to do so?

How to replace NULL% by 0%

In my calculatePercents () method, I should get 0% instead of NULL%.
In my console.log, I get prints with the values NULL
calculatePercents() {
this.v.global.total.amount = this.v.global.cash.amount + this.v.global.sec.amount;
console.log("Cash => " + JSON.stringify(this.v.global.total.amount));
console.log('------------------------');
this.v.global.cash.percent = (this.v.global.cash.amount / (this.v.global.cash.amount + this.v.global.sec.amount)) * 100;
console.log(" Global cash " + JSON.stringify(this.v.global.cash.percent));
this.v.global.sec.percent = (this.v.global.sec.amount / (this.v.global.cash.amount + this.v.global.sec.amount)) * 100;
console.log(" NULL ???? ==> " + JSON.stringify(this.v.global.sec.percent));
var totPercent = (this.v.global.cash.percent + this.v.global.sec.percent);
this.v.global.total.percent = totPercent;
}
How I could get a 0 instead of NULL please.
you can use || operator to set zero
Eg:
this.v.global.total.percent = (totPercent||0);
for more https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR
with || if the first value is false (converted as boolean) then it will take the second, in that case it's used as a default value.
this.v.global.total.percent = totPercent || 0;
You can try this in your method;
if(this.v.global.cash.amount == null){
this.v.global.cash.amount = 0
}
if(this.v.global.sec.amount == null){
this.v.global.sec.amount = 0
}
And then you can do that; (your method)
calculatePercents() {
this.v.global.total.amount = this.v.global.cash.amount + this.v.global.sec.amount;
console.log("Cash => " + JSON.stringify(this.v.global.total.amount));
console.log('------------------------');
this.v.global.cash.percent = (this.v.global.cash.amount / (this.v.global.cash.amount + this.v.global.sec.amount)) * 100;
console.log(" Global cash " + JSON.stringify(this.v.global.cash.percent));
this.v.global.sec.percent = (this.v.global.sec.amount / (this.v.global.cash.amount + this.v.global.sec.amount)) * 100;
console.log(" NULL ???? ==> " + JSON.stringify(this.v.global.sec.percent));
var totPercent = (this.v.global.cash.percent + this.v.global.sec.percent);
this.v.global.total.percent = totPercent;
}
And your veriable type is can be "let".
Simple Code:
let a = null;
if(a==null){
a=0
}
console.log(a);
// output: 0

.append not working on click

Simple button that should be creating new <p> elements when its clicked but it isn't working and I'm not sure why as I've compared it to other code of mine.
Demo
var battle = function() {
while(monsterHP > 0){
var playerDam = Math.floor(Math.random() * ((playerAtk - monsterAtk) + 2);
$('#battle').append("<p>You have hit the monster for " + playerDam + " damage. The monster has " + (monsterHP - playerDam) + "HP left</p>");
monsterHP -= playerDam;
if(monsterHP <= 0) {
$('#battle').append("<p>You have defeated the monster</p>");
}
}
}
$('#battleButton').click(function() {
battle();
}
You have many syntax errors in your code. If you correct them (as below), then it works fine. When you write a JQuery append, you need to put a ')' after your argument. Likewise, functions need to have a '}' after them.
var playerAtk = 5;
var playerDef = 5;
var playerHP = 10;
var monsterAtk = 4;
var monsterDef = 4;
var monsterHP = 8;
var battle = function() {
while(monsterHP > 0){
var playerDam = Math.floor(Math.random() * ((playerAtk - monsterAtk) + 2));
$('#battle').append("<p>You have hit the monster for " + playerDam + " damage. The monster has " + (monsterHP - playerDam) + "HP left</p>");
monsterHP -= playerDam;
if(monsterHP <= 0) {
$('#battle').append("<p>You have defeated the monster</p>");
}
}
}
$('#battleButton').click(function() {
battle();
});

Passing scope as parameter into function to be saved

I have two functions in my controller found below.
$scope.formatPaymentDates = function() {
$scope.formatDate($scope.payment.due_date);
$scope.formatDate($scope.payment.date);
};
$scope.formatDate = function(attr) {
if (attr) {
var split_date = attr.split("-");
if (split_date[0].length == 4) {
attr = split_date[1] + "-" + split_date[2] + "-" + split_date[0];
} else {
attr = split_date[2] + "-" + split_date[0] + "-" + split_date[1];
}
}
};
The problem is that the function formatDate only sets the scope variable attribute and does not save it. What am I missing?
In JavaScript, strings and numbers are passed by value, while objects are passed by reference. You should pass an object as the parameter.
Or, as #faby mentioned, return the value:
$scope.formatPaymentDates = function() {
$scope.payment.due_date = $scope.formatDate($scope.payment.due_date);
$scope.payment.date = $scope.formatDate($scope.payment.date);
};
$scope.formatDate = function(attr) {
var result;
if (attr) {
var split_date = attr.split("-");
if (split_date[0].length == 4) {
result = split_date[1] + "-" + split_date[2] + "-" + split_date[0];
} else {
result = split_date[2] + "-" + split_date[0] + "-" + split_date[1];
}
}
return result;
};
the problem is that you aren't returning any result from your formatDate function.
You are manipulating your variable inside the function and then destroy it.
try this
$scope.formatDate = function(attr) {
if (attr) {
var split_date = attr.split("-");
if (split_date[0].length == 4) {
attr = split_date[1] + "-" + split_date[2] + "-" + split_date[0];
} else {
attr = split_date[2] + "-" + split_date[0] + "-" + split_date[1];
}
return attr;
}
return null
};
and then
$scope.formatPaymentDates = function() {
$scope.payment.due_date= $scope.formatDate($scope.payment.due_date);
$scope.payment.date=$scope.formatDate($scope.payment.date);
};

Zoom into a specific point on an image using mousewheel

I am attempting to build an image zoom/panner using JS/jQuery. I have so far managed to get the zoom working using the mousewheel to zoom in/out, but it currently only zooms in on the center point each time.
Like with Google maps I want to be able to zoom in on the point where the mouse cursor is, but am unsure on the code to do this.
I have setup a fiddle with my progress so far:
http://jsfiddle.net/quirksmode/XrKLN/1/
Any help would be massively appreciated :-)
My code is:
// Plugin to allow for button holds
jQuery.fn.mousehold = function (timeout, f) {
if (timeout && typeof timeout == 'function') {
f = timeout;
timeout = 100;
}
if (f && typeof f == 'function') {
var timer = 0;
var fireStep = 0;
return this.each(function () {
jQuery(this).mousedown(function () {
fireStep = 1;
var ctr = 0;
var t = this;
timer = setInterval(function () {
ctr++;
f.call(t, ctr);
fireStep = 2;
}, timeout);
})
clearMousehold = function () {
clearInterval(timer);
if (fireStep == 1) f.call(this, 1);
fireStep = 0;
}
jQuery(this).mouseout(clearMousehold);
jQuery(this).mouseup(clearMousehold);
})
}
}
/**
* CSS3 Transform helper
*/
var cssTransformScale = function (x, y, z) {
return {
'-webkit-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
'-moz-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
'-ms-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
'-o-transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
'transform': 'scale3d(' + x + ', ' + y + ', ' + z + ')',
};
};
$(document).ready(function () {
var assetViewer = {
name: 'assetViewer',
defaults: {
$assetWrap: $('#asset-wrap'),
$assetImg: $('.asset-img'),
imgSrc: "http://lorempixel.com/1600/760/",
zoomScale: 0.01,
initialZoom: 1,
currentZoom: 1,
maxZoom: 3,
minZoom: 1,
$zoomIn: $('#zoom-in'),
$zoomOut: $('#zoom-out')
},
init: function (options) {
var me = this;
this.options = $.extend(this.defaults, options);
this.appendImage();
this.bindEvents();
},
appendImage: function () {
var me = this;
this.options.$assetWrap.append('<div class="asset-holder"><div class="asset-inner-wrap"><img class="asset-img" src="' + this.options.imgSrc + '" /></div></div>');
me.options.$assetImg = $(me.options.$assetImg.selector); // Using .selector to refresh the element
},
bindEvents: function () {
var me = this;
me.options.$zoomIn.mousehold(1, function () {
me.zoom("+", 1);
})
me.options.$zoomOut.mousehold(1, function () {
me.zoom("-", 1);
})
me.options.$assetImg.mousewheel(function (event, delta) {
if (delta > 0) me.zoom("+", delta);
else if (delta < 0) me.zoom("-", Math.abs(delta)); // Forces the negative to become a positive
return false; // prevent default
});
},
zoom: function (direction, delta) {
var me = this;
//console.log();
if ((me.options.currentZoom >= me.options.minZoom) && (me.options.currentZoom <= me.options.maxZoom)) {
var scale = (direction === "+") ? me.options.currentZoom += (me.options.zoomScale * delta) : me.options.currentZoom -= (me.options.zoomScale * delta);
// Set the Zoom Bounds
if (me.options.currentZoom <= me.options.minZoom) {
scale = me.options.currentZoom = me.options.minZoom;
}
if (me.options.currentZoom >= me.options.maxZoom) {
scale = me.options.currentZoom = me.options.maxZoom;
}
me.options.$assetImg.css(cssTransformScale(scale, scale, scale));
}
}
}
assetViewer.init();
});
I have done something very similar to what you are trying to achieve and I have a div within a div and then used the left and top CSS attributes of the child div to navigate around the image via a minimap image.

Categories