I don't know why my function in the console shows not defined. I have tried to make it right and I just can't seem to get it. It works fine until I try to use the setInterval function. Also the build keeps saying I am missing a semicolon, but I just don't see it.
$(document).ready(function () {
var machineDataViewModel = {
machineDataItems: ko.observableArray([]),
loadMachineDataItems: function DataLoad() {
machineDataViewModel.machineDataItems.length = 0;
$.getJSON("http://localhost/JsonRestful/Service1.svc/GetMachineData", function (data) {
$.each(data.GetMachineDataResult, function (index, item) {
machineDataViewModel.machineDataItems.push(new machineDataModel(item));
});
});
}
};
ko.applyBindings(machineDataViewModel);
machineDataViewModel.loadMachineDataItems();
setInterval(DataLoad, 9000);
});
function machineDataModel(item) {
this.mach_no = ko.observable(item.mach_no),
this.VAR1 = ko.observable(item.VAR1),
this.VAR2 = ko.observable(item.VAR2),
this.VAR3 = ko.observable(item.VAR3),
this.VAR4 = ko.observable(item.VAR4)
};
You can't define the DataLoad() function the way you are and expect it to be available in your setInterval(). It simply doesn't work that way. The symbol DataLoad is only available inside the scope of that function. Instead, you can call it as:
setInterval(machineDataViewModel.loadMachineDataItems, 9000);
Here's a simple demonstration that shows you can't name your function like you are and expect to use that name outside that scope: http://jsfiddle.net/jfriend00/6t0pp60s/ (look in the debug console to see the error).
FYI, if you need your function to have the right value of this (which I don't think you actually do), then you would call it like this (with a semi-colon at the end of every line):
setInterval(machineDataViewModel.loadMachineDataItems.bind(machineDataViewModel), 9000);
As for the semicolon issue, jsHint points to the this.VAR4 assignment line. I'd suggest changing machineDataModel() to this (which gives you a clean bill of health in jsHint):
function machineDataModel(item) {
this.mach_no = ko.observable(item.mach_no);
this.VAR1 = ko.observable(item.VAR1);
this.VAR2 = ko.observable(item.VAR2);
this.VAR3 = ko.observable(item.VAR3);
this.VAR4 = ko.observable(item.VAR4);
}
Related
I have some ambiguity in Javascript callback functions.
The first code is structured as follows:
function firstFunction()
{
var message = "something";
secondFunction(message);
}
function secondFunction(message)
{
var myButton = document.getElementById("my-button");
myButton.addEventListener('click',thirdFunction(message));
}
function thirdFunction(message)
{
console.log("the messages is: "+message);
}
When I run the script above, the thirdFunction gets executed without clicking the button.
After some research, I read about the closure in Javascript. Then I changed the code to the following structure:
function firstFunction()
{
var message = "something";
secondFunction(message);
}
function secondFunction(message)
{
var myButton = document.getElementById("my-button");
myButton.addEventListener('click',thirdFunction);
}
function thirdFunction(message)
{
return function(){
console.log("the messages is: "+message);
}
}
I got the expected result. The thirdFunction is executed only when the button is clicked.
I am not sure if I my second code structure is correct? I am not sure if I'm getting the closure concept correctly as I never returned a function in conventional programming before. This is a new concept to me. Please, correct me if I'm wrong.
EDIT:
Some of the solutions suggest writing it like this:
myButton.addEventListener('click', function() { thirdFunction(message) });
For code readability, I am trying to avoid this. I prefer to place the code for the thirdFunction outside the secondFunction.
Use an anonymous function to make the closure in the correct environment:
function secondFunction(message)
{
var myButton = document.getElementById("my-button");
myButton.addEventListener('click', function() {
thirdFunction(message)
});
}
I am using angularjs/javascript code for image Uploading but i got stuck in variable binding , can anyone help me out, here is my code.
var image_source;
$scope.uploadedFile = function(element) {
reader.onload = function(event) {
image_source = event.target.result;
$scope.$apply(function($scope) {
$scope.files = element.files;
});
}
console.log(image_source,event.target.result, element.files[0], "***not working here***");
I'm binding varibale named image_source within function but when i access this outside the function it always return undefined why ?
PS:- i can get this in the typescript using phatarrow operator but how to do in javascript i dont know
If your console.log statement is called before $scope.uploadedFile which is most likely to be the case, the value will not be set, I suggest you try to call the function and put your console.log statement at the end of the function, inside the block.
That's not an angular issue but more like javascript, when you declare an anonymous function it's not called immediately
let mynumber = 1
let myfunction = () => {
mynumber = 2
}
console.log(mynumber) // 1
myfunction()
console.log(mynumber) // 2
I'm trying to call a function without re-initializing (hope I used the correct word here) it every time I call it. So the first time it gets called, it should initialize, but after its initialized, it should just use that reference.
Here's the code I'm trying to do it with.
JSFiddle
console.clear();
function mainFunction(e) {
var index = 0;
function subFunction() {
console.log(index++);
}
return subFunction();
}
window.addEventListener('click', mainFunction)
index should increase by one every time mainFunction gets called. The obvious solution, is to make index a global variable (or just out of mainFunction). But I need index to stay inmainFunction`.
How can I make index increment every time (using the same reference) mainFunction gets called?
I tried assigning mainFunction to a variable, then calling the variable in the event listener,
var test = mainFunction;
window.addEventListener('click', test)
but that didn't work. The results were the same.
You should correct the code as follows;
console.clear();
function mainFunction(e) {
var index = 0;
function subFunction() {
console.log(index++);
}
return subFunction; // <<< don't invoke subfunction
}
window.addEventListener('click', mainFunction()) // <<< invoke mainfunction
maybe try closures?
var main = (function () {
var index = 0;
return function () {return index += 1;}
})();
main()
main()
//index should be 2...
explain-
The variable main is assigned the return value of a self-invoking function.
The self-invoking function only runs once. index initialize only once.
If you don't want to make index global (or one scope higher regarding mainFunction), you can use a closure:
var mainFunction = (function () {
var index = 0;
return function () {return console.log(index++);}
})();
<button onclick="mainFunction()">Click</button>
Using OOP concept is the proper way to achieve this. The following should help you.
If you want to do it in ES6 way follow this babel example
var mainFunction = function(val) {
this.index = val //initialize this with the fn parameter or set a atatic value
}
mainFunction.prototype.subFunction = function() {
return this.index++
}
var instance = new mainFunction(0)
window.addEventListener('click', function() {
console.log(instance.subFunction())
})
<p>Click to see the result </p>
Preety straight forward question, though I can't find the answer anywhere
I tried these two ways:
setInterval(function(){object/*or this*/.method()},500)
and
setInterval('object/*or this*/.method()',500)
setInterval in fact expects a method as the first argument, though there is an alternative syntax where the first argument can be a string of code (not recommended by most)
If you're having issues with that code, it may have to do with the scope of 'this'
setInterval(function(){this.method()},500)
In the above code, 'this' will refer to the closure itself, and wouldn't be the same as 'this.method' occurring outside of that closure. For example, the following would work:
function MyClass() {
this.thingy = 'yep this is a thingy'
}
var myClass = new MyClass()
// Will log 'MyClass yep this is a thingy'
setInterval(function() { console.log('MyClass', myClass.thingy) }, 1000)
Whereas the following will not work (presuming instantiating the object and calling foo()):
function MyOtherClass() {
this.thingy = 'also a thingy'
}
// Will log 'MyOtherClass undefined'
MyOtherClass.prototype.foo = function() {
setInterval(function() { console.log('MyOtherClass', this.thingy) }, 1000)
}
The second example will work if we get around using 'this' within the closure (presuming instantiating the object and calling bar()):
MyOtherClass.prototype.bar = function() {
var that = this
setInterval(function() { console.log('MyOtherClass', that.thingy) }, 1000)
}
Also be sure that setInterval is being passed the name of a function:
setInterval(someFunction, 500)
rather than executing a function as an argument
setInterval(someFunction(), 500)
This last line of code is usually a mistake, unless someFunction() returns a function itself ;)
The difference between your 2 ways for passing a function to setInterval is whether you want to pass your function as refrence of just copy of it. Allow me to explain it by example:
-1 Referring(demo):
var obj = {
testMethod: function () {
console.log('function (testMethod): intial output');
}
}
setInterval(function () {
obj.testMethod()
}, 1000);
obj.testMethod = function () {
console.log('function (testMethod): changed output');
}
when you run this code, the result 'll be execution of the modified version of testMethod. Because here you dont copy the function! Instead, you refer to it. So whenever function implementation is changed, the last modified version is executed.
-2 Copying(demo):
var obj = {
testMethod: function () {
console.log('function (testMethod): intial output');
}
}
setInterval(obj.testMethod, 1000);
obj.testMethod = function () {
console.log('function (testMethod): changed output');
}
Here all you do is you are passing a copy of the last defined version of the function testMethod to setInterval. So whatever changes you do to testMethod, the result of setInterval will not be changed.
Ok, this may sound a bit crazy but hear me out :)
I would like to do the following in javascript:
define START_OF_EVERY_FUNCTION = "try {"
define END_OF_EVERY_FUNCTION = "} catch () {}"
function TEST () {
START_OF_EVERY_FUNCTION
// rest of function
END_OF_EVERY_FUNCTION
}
Basically, can I define a list of javascript lines (code) and include them as above? I'm looking for a technique versus comments about whether this is a good idea or not or debate over wrapping all functions in a try/catch block.
I know about eval(), but I dont think you can eval statements like the above.
This might be goofy but you could define a master function and run other functions through it by passing them in.
var execute = function(func){
alert('before');
func();
alert('after');
};
function sayHi(){
alert('hi there');
}
execute(sayHi);
As requested, an example with passing arguments.
var execute = function(func){
alert('before');
var ret = func.apply(null, Array.prototype.slice.call(arguments, 1));
alert('after');
};
function saySomething(sayWhat){
alert(sayWhat);
}
execute(saySomething,'hey there');
That is not allowed in JavaScript.
You could extend the Function prototype:
Function.prototype.tryThis = function() {
try {
this();
}catch(ex){
alert('Caught '+ex);
};
};
function tryIt() {
alert('Inside tryIt');throw "My Error from tryIt";
}
tryIt.tryThis();
You need to look into aspect oriented programming for JavaScript. You can create hooks for function entry and exit. Tools like JSUnit do this for example.
I think you can do this with the "new Function" operator. I've never used it myself, since I'm not clinically insane, but I believe you can pass it a string which it will evaluate and use as the function body. You can also get the code for each function by calling myFunction.toString(). So put together, it'd be something like this:
var functionsToMessUp = ['myFunc1', 'myFunc2'];
for (var i = 0; i < functionsToMessUp.length; ++i) {
var theFunc = window[functionsToMessUp[i]]; // assuming they're in global scope
window[functionsToMessUp[i]] = new Function(
START_OF_EVERY_FUNCTION
+ theFunc.toString()
+ END_OF_EVERY_FUNCTION
);
}
Now, the above almost certainly won't work - there's parameters and other things to take into consideration, and I don't even think that's how the new Function constructor works, but if you really want to go down this path (which I really don't recommend), then this might be a good starting point for you.
Maybe something like this?
function tryCatch(callback) {
try {
callback();
} catch() {}
}
var myFunction = function() {
// do some stuff
};
tryCatch(myFunction);