Result of expression 'this.getURL'[undefined] is not a function - javascript

When i call a method directly without a setInterval the function works correctly
slider.prototype.onTouchEnd = function(e){
clearInterval(this.inter);
this.getURL(this.url + '/' + this.eid.id + '/' + this.currX);
e.preventDefault();
}
putting the same function in a setInterval give me following error:
Result of expression 'this.getURL'[undefined] is not a function
slider.prototype.onTouchStart = function(e){
e.preventDefault();
this.inter = setInterval("this.getURL('www.google.com')",100);
}
the code of getURL is:
slider.prototype.getURL = function(url){
console.log(url);
verzoek=new XMLHttpRequest();
verzoek.onreadystatechange=function(){
if(verzoek.readyState==4) {
if(verzoek.status==200) {
var data=verzoek.responseText;
}
}
}
verzoek.open("GET", url, true);
verzoek.send(null);
}
the this.inter is created in the constructor
var slider = function(eid){
...
this.inter = null;
}
I tried so many things but it keeps failing.
Thx in advance

You need to pass a real function to setInterval, you are currently passing a string.
If you change it to:
slider.prototype.onTouchStart = function(e){
e.preventDefault();
var that = this;
this.inter = setInterval(function(){that.getURL('www.google.com');},100);
}
Does it work?

Related

Callback function not receiving data after function returns data from API endpoint

On-Click Function
$(".action-open-instruction-confirm").on("click",
function(event) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber, function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
Endpoint function
function getInstructionType(applicationNumber) {
if (window.location.port !== "") {
port = ":" + window.location.port;
} else {
return null;
}
var url = window.location.protocol +
"//" +
window.location.hostname +
port +
"-apiEndpoint-?applicationNumber=" +
applicationNumber;
$.get(url,
function(data) {
return data; //<-- Change this to $("#InstructionConfirm #instruction-confirm-instruction-type").html(data); and it works correctly
});
}
HTML
<div id="InstructionConfirm">
<span id="instruction-confirm-instruction-type"></span>
</div>
I have the two functions above that I am trying to use to alter the HTML of the `#instruction-confirm-instruction-type element present in my HTML. The problem is that at the moment the callback function doesn't seem to be functioning properly.
The On-Click function passes the applicationNumber to the getInstructionType function which then calls an API endpoint. This endpoint works correctly and returns the data with no issues. However it then seems like the return data; line in my getInstructionType function doesn't seem to be returning the data properly, as the callback function in the on-click is never executed.
I know the callback is not being executed as it doesn't trigger the breakpoint I have on the $("#InstructionConfirm #instruction-confirm-instruction-type").html(data); line.
If I then replace the return data; line in the second function with $("#InstructionConfirm #instruction-confirm-instruction-type").html(data);, then I get the behaviour I am expecting with no issues.
What exactly is preventing getInstructionType from returning the data to my callback function for it to be used within the on-click function?
The issue is because you don't do anything with the callback you provide. You don't create an argument in the function definition for it, and you don't call it from $.get(). Try this:
$(".action-open-instruction-confirm").on("click", function(e) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber, function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
function getInstructionType(applicationNumber, callback) { // accept the 'callback' argument
if (window.location.port !== "") {
port = ":" + window.location.port;
} else {
return null;
}
var url = window.location.protocol + "//" + window.location.hostname + port + "-apiEndpoint-?applicationNumber=" + applicationNumber;
$.get(url, callback); // invoke the callback when $.get receives data
}
Also note that you can just use location.origin instead of manually building the protocol/domain/port string:
var url = window.location.origin + "-apiEndpoint-?applicationNumber=" + applicationNumber;
Although it looks like you may be missing a / after the port as your URL will currently include the string after the port which appears to be incorrect.
Your function doesn't have a parameter for the callback:
function getInstructionType(applicationNumber) {
should be:
function getInstructionType(applicationNumber, callback) {
you can then add your callback
$.get(url,
function(data) {
if ($.isFunction(callback))
callback(data);
});
or even just:
$.get(url, callback)
You might like to consider using promises instead, eg:
$(".action-open-instruction-confirm").on("click",
function(event) {
var applicationNumber = $('.case-application-number').val();
getInstructionType(applicationNumber).done(function(data) {
$("#InstructionConfirm #instruction-confirm-instruction-type").html(data);
});
});
function getInstructionType(applicationNumber) {
....
return $.get(url);

Identify the caller (or how pass parameter) of a callback (JSON) function in JavaScript

When i request
BASE_URL + 'json/valueone?callback=fnCallBack0'
the response from server is treated in a callback function. This function receives (ASYNCHRONOUS) data (JSON format) but do not include the initial parameter "valueone"
var BASE_URL = ...
function fnCallBack(data){
if (data != null) {
// HERE...I NEED ID <====================
// arguments.callee.caller <==================== dont work
console.log('information', data);
}
}
// onclick callback function.
function OnClick(info, tab) {
var arrH = ['valueone', 'valuetwo'];
arrH.forEach(function(value) {
var scrCallBack = document.createElement('script');
scrCallBack.src = BASE_URL + 'json/' + value + '?callback=fnCallBack';
//BASE_URL + 'json/one?callback=fnCallBack0';
document.body.appendChild(scrCallBack);
});
My solution is to create an intermediate function correlative name (fnCallBack0, fnCallBack1, ...), a global array, and a counter. Works fine, but this is not OOP, is a fudge.
var BASE_URL = ...
//global array
var arrH = [];
var fnCallBack0 = function(data){
fnCallBack(data, '0');
}
var fnCallBack1 = function(data){
fnCallBack(data, '1');
}
function fnCallBack(data, id){
if (data != null) {
console.log('information', data + arrH[id]);
}
}
// onclick callback function.
function OnClick(info, tab) {
var i = 0;
arrH = ['valueone', 'valuetwo'];
arrH.forEach(function(value) {
var scrCallBack = document.createElement('script');
scrCallBack.src = BASE_URL + 'json/' + value + '?callback=fnCallBack' + (i++).toString();
//BASE_URL + 'json/one?callback=fnCallBack0';
document.body.appendChild(scrCallBack);
});
chrome.contextMenus.create({
title: '%s',
contexts: ["selection"],
onclick: function(info) {console.log(info.selectionText)}
});
var idConsole = chrome.contextMenus.create({
title: 'console',
contexts: ["selection"],
onclick: OnClick
});
I tried with inject function as code in html page, but i receeived "inline security error", and a lot of similar questions.
Please, NO AJAX and no jQuery.
This is my first post and my first chrome extension
Thanks in advanced.
I don't see how anything of this has to do with OOP, but a solution would be to just create the callback function dynamically so that you can use a closure to pass the correct data:
function fnCallBack(data, value){
if (data != null) {
console.log('information', data + value);
}
}
// onclick callback function.
function OnClick(info, tab) {
['valueone', 'valuetwo'].forEach(function(value, index) {
// unique function name
var functionName = 'fnCallback' + index + Date.now();
window[functionName] = function(data) {
fnCallBack(data, value);
delete window[functionName]; // clean up
};
var scrCallBack = document.createElement('script');
scrCallBack.src = BASE_URL + 'json/' + value + '?callback=' + functionName;
document.body.appendChild(scrCallBack);
});
}

using .ajax() in .each()

I'm trying to iterate through elements of .ball class and check if their associated url exists:
$(".ball").each(function(i){
var url;
var c_day = $(this).data('day');
var c_mon = $(this).data('mon');
var c_year = $(this).data('year');
url = c_year + "/" + c_mon + "/" + c_day + ".html";
$.ajax({
url: url,
error: function()
{
alert('file: ' + url + ' does not exist');
},
success: function()
{
alert('file: ' + url + 'EXXXXXXISTS!!!!!');
blogA[ blog_count ] = url;
blog_count++;
$(this).css("color", "red" );
}
});
});
I've done some research and read that using .ajax in .each causes a lot of problems but I couldn't wrap my head around on how to fix it.
The problem is that I get really weird results (has to do with asynchronous?). If I alert url outside of ajax, it correctly iterates through the elements. If I alert url in ajax, it spits out urls that belong to the last element of the class.
Something like this, in order to simplify your code
function successHandler(url, ball) {
return function(ret) {
alert('file: ' + url + 'EXXXXXXISTS!!!!!');
ball.css('color','red')
}
}
var balls = $('.ball'), requests = []
balls.each(function(index, ball) {
var url = ...
requests.push($.ajax({ url : url , success : successHandler(url, ball) })
})
$.when.apply($, requests).done(function() {
alert('all balls are checked')
})
Or with ES6:
const success = (url,ball)=>(ret)=>ball.css('color','red')
const balls = $('.balls')
, reqs = balls.map( (b, i) => {
const url = ...
return $.ajax({url, success:success(url,ball)})
})
$.when.apply($, reqs).done( (resps) => alert('all done'))
A Little explanation: You are blindly using this in your callback, not knowing in which context it is going to be executed. In order to work around it and has your URL into callback we are creating function that returns a function, so it will have URL of current .ball DOM object in the context.
You'll probably also need to execute code after all ajax requests are done, so using $.when is the simplest way of doing it. And we are storing all promises just for this reason.
If you aren't concerned about the order of execution of each ajax call and just want to know when they are all done and the array is fully populated, then you can get this to work by fixing your reference to this and by adding a callback function that is called when all items are done:
// this function called when the ajax calls for all balls have finished
// at this point, blogA and blog_count will be populated
function ballsDone() {
// put your code here
}
var balls = $(".ball");
var cnt = balls.length;
balls.each(function(i){
var url;
var self = $(this);
var c_day = self.data('day');
var c_mon = self.data('mon');
var c_year = self.data('year');
url = c_year + "/" + c_mon + "/" + c_day + ".html";
$.ajax({
url: url,
error: function()
{
alert('file: ' + url + ' does not exist');
if (--cnt <= 0) {
ballsDone();
}
},
success: function()
{
blogA[ blog_count ] = url;
blog_count++;
self.css("color", "red" );
if (--cnt <= 0) {
ballsDone();
}
}
});
});
Keep in mind that the ajax calls are asynchronous so the ONLY place you can use the results from the ajax call is in the success handler. You can't use the results of the ajax calls right after the .each() call in a synchronous fashion because the ajax calls have not yet finished. You must wait for the success handler to be called and when cnt success handlers have been called, then they are all done and you can then process the results.

jquery passing array data to function

I have made a function to get the variable of onclick and pass it to the function, but I want it in different format:
$('.ajax').live('click', function() {
var Loading = 'Loading...';
var url = $(this).attr('href');
var container = '#myDivcontent';
looadContents(url,Loading,container);
return false;
});
and the function looks like :
looadContents(url,Loading,container) {
..
...
$(contaner).load(url);
...
..
}
I would like to have like array format or json data format when I call the function:
$('.ajax').live('click', function() {
looadContents({
url : $(this).attr('href'),
Loading : 'Loading...',
container: '#myDivcontent'
});
return false;
});
Any idea how can I do this?
If you pass the information like an object, you can simply access it as one:
function looadContents(options) {
$(options.container).load(options.url);
}
looadContents({ url: '...', container: '#...' });
This syntax works as expected.
function display(obj)
{
console.log(obj.name + " loves " + obj.love);
}
display({name:"Jared", love:"Jamie"});
Is this possibly what you are looking for?
function looadContents(o) {
alert(o.url);
alert(o.container);
}
looadContents({ url:"abc", container: "def" });
Use what's sometimes called an "options" object (what you refer to as "JSON data format" is simply a JavaScript object literal):
function loadContents(options) {
var url = options.url;
var Loading = options.Loading;
/* etc. */
}
You can also leverage this approach to provide default values for certain parameters:
function loadContents(options) {
var url = options.url || "http://default-url.com/",
var Loading = options.Loading || "Loading...";
var container = options.container || "#container";
$(container).load(url);
}
Try this
looadContents(input) {
//...
$(input.contaner).load(input.url);
//...
}

Use jQuery to replace XMLHttpRequest

I am quite new to JavaScript libraries. I wanted to replace my current code with jQuery. My current code looks like this:
var req;
function createRequest() {
var key = document.getElementById("key");
var keypressed = document.getElementById("keypressed");
keypressed.value = key.value;
var url = "/My_Servlet/response?key=" + escape(key.value);
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
req.open("Get", url, true);
req.onreadystatechange = callback;
req.send(null);
}
function callback() {
if (req.readyState == 4) {
if (req.status == 200) {
var decimal = document.getElementById('decimal');
decimal.value = req.responseText;
}
}
clear();
}
I wanted to replace my code with something a little friendlier like jQuery's
$.get(url, callback);
However it doesn't call my callback function.
Also I would like to call a function called createRequest continuously. Does jQuery have a nice way of doing that?
­­­­­­­­­­­­­­­­­­­­­­­
$.get(url, {}, callback);
should do the trick. Your callback could be simplified like this:
function callback(content){
$('#decimal').val(content);
}
Or even shorter:
$.get(url, {}, function(content){
$('#decimal').val(content);
});
And all in all I think this should work:
function createRequest() {
var keyValue = $('#key').val();
$('#keypressed').val(keyValue);
var url = "/My_Servlet/response";
$.get(url, {key: keyValue}, function(content){
$('#decimal').val(content);
});
}
Take out the readyState and status checks. jQuery only calls your callback upon success. Your callback is supplied the arguments (data, textStatus), so you should use data instead of req.responseText.
window.setTimeout() as suggested by another answer won't do what you want - that only waits and then calls your function once. You need to use window.setInterval() instead, which will call your function periodically until you cancel it.
So, in summary:
var interval = 500; /* Milliseconds between requests. */
window.setInterval(function() {
var val = $("#key").val();
$("#keypressed").val(val);
$.get("/My_Servlet/response", { "key": val }, function(data, textStatus) {
$("#decimal").val(data);
});
}), interval);
I don't think jQuery implements a timeout function, but plain old javascript does it rather nicely :)
According to the docs, jQuery.get's arguments are url, data, callback, not url, callback.
A call to JavaScript's setTimeout function at the end of your callback function should suffice to get this to continually execute.
There's no need to set the GET parameters on the URL, jQuery will set them automatically. Try this code:
var key = document.getElementById("key");
[...]
var url = "/My_Servlet/response";
$.get (url, {'key': key}, function (responseText)
{
var decimal = document.getElementById ('decimal');
decimal.value = responseText;
});
In the end I guess it was added the type. This seems to work for me.
function convertToDecimal(){
var key = document.getElementById("key");
var keypressed = document.getElementById("keypressed");
keypressed.value = key.value;
var url = "/My_Servlet/response?key="+ escape(key.value);
jQuery.get(url, {}, function(data){
callback(data);}
, "text" );
}
function callback(data){
var decimal = document.getElementById('decimal');
decimal.value = data;
clear();
}
Thanks Everyone for the help. I'll vote you up.

Categories

Resources