setting callback property value to null - javascript

Im wondering in the following code, how could I set the callback property "value" to null?
The code takes a bunch of ids (31, 32 ,33) and then uses a callback function to monitor changes to values of these ids. When I run the code again using the same IDs, is there a way to set the callback property to null?
obsids = new Array();
function list() {
if (arguments.length) {
leng = arguments.length;
for (i = 0; i < leng; i++) {
obsids[i] = new LiveAPI(callback, "id "+arguments[i]);
obsids[i].property = "value";
}
}
function callback(args) {
outlet(0, args[0] + " " + args[1] + " " + this.id);
}
}

You will need a specific callback for each obsids[i], and you need to create them in a closure for not loosing i.
function list() {
var obsids = [];
for (var i=0, len = arguments.length; i < len; i++)
obsids[i] = createApi("id "+arguments[i]);
function createApi(id) {
var obsid = new LiveAPI(function callback(args) {
obsid.property = null;
outlet(0, args[0] + " " + args[1] + " " + this.id);
}, id);
obsid.property = "value";
return obsid;
}
return obsids;
}

Related

Complicated Javascript object creation and rewriting issue. Set of Undefined error

function reworkInfoData(jsonData){
var userData = [];
userData[0] = {
date: ' ',
data: []
};
userData[0].data[0] = {
activity: ' ',
time: ' '
}
var timeVar = new Date();
for(var i = 0; i < jsonData.length; i++){
timeVar = new Date(jsonData[i].date);
userData[i].date = timeVar.getFullYear() + '.' + timeVar.getMonth() +
'.' + timeVar.getDay();
for(var k = 0; k < jsonData[i].data.length; k++){
userData[i].data[k] = jsonData[i].data[k];
}
}
return UserData;}
I'm learning node.js, and for studiyng purposes im trying to write something like study loger using express and ejs. This block of code higher was used to rewrite the JSON date string to the pretty looking one. And i keep getting an error
TypeError: Cannot set property 'date' of undefined
at
userData[i].date = ...
Lot of things are wrong/bad practise the way you have done this.
1.Instead of code below:
var userData = [];
userData[0] = {
date: ' ',
data: []
};
Try:
var userData = [];
userData.push({
date: ' ',
data: []
});
2.You are checking for jsonData value in : for(var i = 0; i < jsonData.length; i++) but you are accessing userData with the iterator. userData[i].date this will fail when userData.length is lesser than jsonData.length. Change your logic to fix this.
Your userData array initially has only one object, so if your jsonData has length more than one than, you will get this error since userData[1] or so on is not defined
Try this
function reworkInfoData(jsonData){
var userData = [];
userData[0] = {
date: ' ',
data: []
};
userData[0].data[0] = {
activity: ' ',
time: ' '
}
var timeVar = new Date();
for(var i = 0; i < jsonData.length; i++){
timeVar = new Date(jsonData[i].date);
if(userData[i]) {
userData[i].date = timeVar.getFullYear() + '.' + timeVar.getMonth() +
'.' + timeVar.getDay();
for(var k = 0; k < jsonData[i].data.length; k++){
if(userData[i].data[k]) {
userData[i].data[k] = jsonData[i].data[k];
}else {
userData[i].data.push(jsonData[i].data[k])
}
}
} else {
var tmp = {};
tmp.date = timeVar.getFullYear() + '.' + timeVar.getMonth() +
'.' + timeVar.getDay();
for(var k = 0; k < jsonData[i].data.length; k++){
tmp[i].data.push(jsonData[i].data[k]);
}
}
}
return UserData;
}

How to access the current element property name of the called function

For logging purpose, I've created a wrapper function for an element functions properties.
The wrapper function is above:
functionsWrapper: function () {
for (i = 0, args = new Array(arguments.length); i < arguments.length; i++) {
args[i] = arguments[i];
}
console.log('call for ' + arguments.callee.name + ' with params ' + argumantsLog(args));
return this['original' + arguments.callee.name].apply(this, args);
}
And then I'm using this code to wrap the element function:
logFunctionsCalls: function (element) {
if (!element)
return;
if (element.children && element.children.length)
for (var i = 0; i < element.children.length; i++)
logFunctionsCalls(element.children[i]);
if (!element.functionsLogged) {
element.functionsLogged = true;
for (var property in element) {
if (typeof element[property] != 'function')
continue;
element['original' + property] = element[property];
element[property] = functionsWrapper;
}
}
}
My problem is that the arguments.callee contains the functionsWrapper code without the property name of the called function.
You cannot use the same functionWrapper everywhere - there's no way to find out as which property it was called. Instead, created different wrappers and keep the original in closure.
for (var p in element) (function(property) {
if (typeof element[property] != 'function')
return;
var original = element[property];
element[property] = function wrapped() {
console.log('call for ' + property + ' with params ' + Array.prototype.join.call(arguments));
return original.apply(this, arguments);
};
}(p));

Array length remains 0 even though I push 'objects' to it

I have a little piece of code that reads some ajax (this bit works) from a server.
var self = this;
var serverItems = new Array();
var playersOnlineElement = $("#playersOnline");
function DataPair(k, v) {
this.key = k;
console.log("new datapair: " + k + ", " + v);
this.value = v;
}
DataPair.prototype.getKey = function() {
return this.key;
}
DataPair.prototype.getValue = function() {
return this.value;
}
$.getJSON("http://127.0.0.1", function(data) {
$.each(data, function(key, val) {
var pair = new DataPair(key, val);
self.serverItems.push(pair);
});
});
console.log(serverItems.length); //Problem is here
for (var i = 0; i < serverItems.length; i = i + 1) {
var dpair = serverItems[i];
if (dpair.getKey() === "playersOnline") {
self.playersOnlineElement.text("Players Online: " + dpair.getValue());
}
}
The datapair and the JSON get loaded but when they are pushed to the array it doesn't seem to work. I tried with self.serverItems and just serverItems because netbeans showed me the scope of the variables being good if I used just serverItems but I am a bit confused as to why this doesn't work. Can anyone help me?
I put in comments where the error is. serverItems.length is 0 even though when debugging in a browser in the DOM tree it has an array serverItems with all the data inside.
Assumingly this serverItems is in another scope and not the one I am calling when I want to get the length?
add this code into the success part, since its asynchronous...
for (var i = 0; i < serverItems.length; i = i + 1) {
var dpair = serverItems[i];
if (dpair.getKey() === "playersOnline") {
self.playersOnlineElement.text("Players Online: " + dpair.getValue());
}
to...
$.getJSON("http://127.0.0.1", function(data) {
$.each(data, function(key, val) {
var pair = new DataPair(key, val);
self.serverItems.push(pair);
for (var i = 0; i < serverItems.length; i = i + 1) {
var dpair = serverItems[i];
if (dpair.getKey() === "playersOnline") {
self.playersOnlineElement.text("Players Online: " + dpair.getValue());
}
});
});

JS and jQuery, global object gets empty when function is finished

I have a problem with an object dict. When json datas are received, program calls LoadDict() function, where dict object gets filled with new data from server. I used FireBug to make sure that dict has all new elements with correct information, but when function is finished, dict gets empty again like it was before ajax request. This code executes in the global scope:
var dict = new Dictionary();
function LoadDict(words) {
for (var i in words) {
var word = new Word();
word.word = words[i].Word;
word.transcript = words[i].Transcript;
word.frequency = words[i].Frequency;
word.meanings = words[i].Meanings;
word.examples = words[i].Examples;
word.imgLinks = words[i].ImgLinks;
dict.Add(word);
}
}
$.getJSON("getall").done(LoadDict);
dict.PrintDictionary);
And this is some code of my Dictionary class
function Dictionary() {
this.collection = new Array();
this.count = 0;
this.sorted = false;
}
Dictionary.prototype.Add = function(word) {
if (word instanceof Word) {
word.id = this.count;
this.collection[this.count] = word;
this.count++;
this.sorted = false;
}
}
Dictionary.prototype.PrintDictionary = function() {
function WordToString(word) {
var line = "<strong>" + word.word + "</strong> [" + word.transcript + "] - " + word.meanings[0];
for (var j = 1; j < word.meanings.length; j++) {
line += ", " + word.meanings[j];
}
return line;
}
var result = "<ol>"
for (var i = 0; i < this.collection.length; i++)
result += "<li>" + WordToString(this.collection[i]) + "</li>";
result += "</ol>"
document.write(result);
}
Declaration of Dictionary class goes before creating dict object.
Help, please!
A timing problem.
In your code, PrintDictionary function have excuted before ajax call is complete.
The problem is that the $.getJSON is async.
This means that the dict.PrintDictionary(); line gets executed before the result is returned from the getJSON call

Javascript methods recalling and printing

I'm studying JavaScript and I've some problems with the recall of functions...
These are my two functions:
the first:
function geisson() {
var iabile = new XMLHttpRequest();
iabile.onreadystatechange = function () {
if (iabile.readyState == 4) {
var objectjson = {};
var arrayCards = []; //creazione dell'array che conterrà le cards
objectson = JSON.parse(iabile.responseText);
arrayCards = objectson.cards;
var Ettore = []; //Vèttore di cards
//the results
for (i = 0; i < arrayCards.length; i++)
document.getElementById('image').src = "http://www.mysite.com/png/public/card/" + arrayCards[i].__guid__ + "?width=292";
}
}
iabile.open("GET", "gnekcard.json", true);
iabile.send(null);
}
and the second function:
function Entity() {
var iabile = new XMLHttpRequest();
iabile.onreadystatechange = function () {
if (iabile.readyState == 4) {
var objectjson = {};
var arrayCards = []; //creazione dell'array che conterrà le cards
objectson = JSON.parse(iabile.responseText);
arrayCards = objectson.cards;
//the results
for (i = 0; i < arrayCards.length; i++)
document.getElementById('informazioni').innerHTML += "\r\n" + "Nome : " + arrayCards[i].__title__ + "\r\n" + "Vanity url: " + arrayCards[i].vanity_urls[0] + "\r\n";
}
}
iabile.open("GET", "gnek.json", true);
iabile.send(null);
}
I would like to have a third function that prints the results of the other 2 functions. I'd prefer to have the "for" in only in the third function and recall the vectors of the others methods but they aren't global. I don't want to have global variables (if possible) so how can I do it?
In the geisson function you can do this:
geisson.arrayCards = arrayCards;
and you can do the same in the Entity function
Entity.arrayCards = arrayCards;
Then you can create a third function that can access the arrayCards of each function.
function displayArrayCards {
var geissonCards = geisson.arrayCards;
var EntityCards = Entity.arrayCards;
var i;
for(i = 0; i < geissonCards.length; i++) {
document.getElementById('image').src = "http://www.mysite.com/png/public/card/" + geissonCards[i].__guid__ + "?width=292";
}
for(i = 0; i < EntityCards.length; i++) {
document.getElementById('informazioni').innerHTML += "\r\n" + "Nome : " + EntityCards[i].__title__ + "\r\n" + "Vanity url: " + EntityCards [i].vanity_urls[0] + "\r\n";
}
}
Do what you should always do when you work with Ajax calls: Use callbacks.
For example:
function geisson(callback) {
var iabile = new XMLHttpRequest();
iabile.onreadystatechange = function () {
if (iabile.readyState == 4) {
// ...
callback(objectson.cards);
}
}
iabile.open("GET", "gnekcard.json", true);
iabile.send(null);
}
and in your third function:
function someName() {
geisson(function(data) {
for (var i = 0; i < data.length; i++) {
//... do something with data ...
}
});
// call Entity the same way here...
}
Btw, in your first function, you always override the src property of the same element (document.getElementById('image')). It does not make sense to iterate over the whole array here, sine eventually, src will have the value related to the last element. Either assign the values to multiple elements or just get the last element in the array.

Categories

Resources