Javascript - Array of 'classes' - javascript

I'm trying to create an array of 'classes' like so:
function Main(initURL){
var item_array = [];
this.initURL = initURL;
function construct() {
$.ajax({
url: initURL,
dataType: 'json',
success: function(data){
for(var i=0;i<data.length;i++){
var item = new Item(data[i]);
item_array.push(item);
}
init();
}
});
}
function init() {
setInterval(update, 1000);
}
function update() {
for(var item in item_array){
console.log(item.name);
}
}
construct();
}
function Item(data) {
var dirty = false;
function init(data) {
this.id = data.pk;
this.name = data.fields.name;
}
init(data);
}
When attempting to print out the item name, I'm getting "undefined". Is there more to it than this? Data.field.name is definitely set.

A for..in loop loops through keys, not values. Change it to:
for(var i = 0; i < item_array.length; i++) {
console.log(item_array[i].name);
}

Don't use for... in to iterate over an array.
for(var i=0; i < item_array.length; i++){
console.log(item_array[i].name);
}
https://developer.mozilla.org/en/JavaScript/Reference/Statements/for...in#Description

The problem is that you're calling your "init()" function in "Item()" without any context object. Thus, this isn't the object you want it to be. Try this change:
function Item(data) {
var item = this;
function init(data) {
item.id = data.pk;
item.name = data.fields.name;
}
init(data);
}
Now, I'm not sure why you'd want to write the function that way in the first place; that little "init()" function doesn't really do anything useful. It could just be:
function Item(data) {
this.id = data.pk;
this.name = data.fields.name;
}
and that would work too.

Related

How to loop an object returned by a function in another function in JS?

i've a problem in js. I've a function for example:
function robePersos() {
var persos = {"player" : "data"};
return persos;
}
and then i've another function which call robePersos() like this:
function test() {
var d = robePersos();
for(var k in d) {
console.log(k)
}
}
But nothing happens. Why ?
function robePersos() {
var persos = {
"player": "data"
};
return persos;
}
function test() {
var d = robePersos();
for (var k in d) {
console.log(k)
}
}
test();
EDIT
The first snippet works. So, here is my real function:
function robePersos() {
var persos = {};
$.get({
url : 'url',
success : function(data) {
var text = $(data).find("div[menu='perso'] a"); //.clone().children().remove().end().text();
$(text).each(function(){
perso_name = $(this).text();
perso_link = $(this).attr('href');
persos[perso_name] = perso_link;
});
}
});
for(var k in persos) {
console.log(persos[k]);
}
}
robePersos();
If I replace the loop by only console.log(persos) it works but the loop return nothing. Why ?
If you want to print both Key and Value, use the following small change in your code. Your code is printing just the keys.
function robePersos() {
var persos = {
"player": "data",
"anotherPlayer": "anotherData"
};
return persos;
}
function test() {
var d = robePersos();
for (var k in d) {
console.log(k, "-" ,d[k]); // change made here. It prints both.
}
}
test();
Try whith Object.keys()
function test() {
var d = Object.keys(robePersos());
for (var k in d) {
console.log(k, "-" ,d[k]); // change made here. It prints both.
}
}
Object.keys returns an array whose elements are strings corresponding to the enumerable properties found directly in the object. The order of the properties is the same as that provided when manually iterating over the properties of the object.
https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/keys

javascript setInterval not repeating in jquery

function get_stock_data(symbol, index) {
var url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22"+ symbol +"%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=";
$.getJSON(url, function(data) {
var price = $(".stock-price");
price[index].innerHTML = "";
price[index].appendChild(document.createTextNode(data.query.results.quote.Change));
console.log(data);
}).success(function() {
console.log("success");
}).fail(function() {
console.log("Failed");
});
}
$("document").ready(function() {
var symbol = $(".stock-symbol");
for(var i = 0; i < symbol.length; i++) {
setInterval(get_stock_data(symbol[i].firstChild.textContent, i) , 1000);
console.log("hello");
}
});
The problem in this script is that get_stock_data function executes only once...plz help...i want the data to be updated to DOM..
Something like this should work.
function get_stock_data(symbol, index) {
var url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22" + symbol + "%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=";
$.getJSON(url, function (data) {
var price = $(".stock-price");
price[index].innerHTML = "";
price[index].appendChild(document.createTextNode(data.query.results.quote.Change));
console.log(data);
}).success(function () {
console.log("success");
}).fail(function () {
console.log("Failed");
});
}
function setUpInterval() {
var symbol = $(".stock-symbol");
for (var i = 0; i < symbol.length; i++) {
setInterval("get_stock_data(" + symbol[i] + "," + i + ")", 1000);
}
}
setUpInterval();
You are calling get_stock_data in your setInterval call. So it gets called once and only once. You are actually passing undefined to setInterval, because get_stock_data doesn't return anything.
The first argument of setInterval should be the function you want to call. In this case, it looks like you want to call get_stock_data with some passed-in parameters. To make this work with setInterval, you'll need to pass in an anonymous function like this:
for (var i = 0; i < symbol.length; i++) {
setInterval(function() { get_stock_data(symbol[i].firstChild.textContent, i); }, 1000);
}
This way you are passing in the function to setInterval, which setInterval will call every 1000 (or so) milliseconds.

Simplify the code by using cycle function

I have multiply functions which are using the same cycle code and i'm wondering is it possible to simplify the code by having one cycle function so i could execute the code just by calling wanted function names.
Now:
for(var i=0;i<all;i++){ someFunction(i) }
Need:
cycle(someFunction);
function cycle(name){
for(var i=0;i<all;i++){
name(i);
}
}
I tried to do this by using "window" and i get no error but the function is not executed.
var MyLines = new lineGroup();
MyLines.createLines(); // works
MyLines.addSpeed(); // doesn't work
var lineGroup = function(){
this.lAmount = 5,
this.lines = [],
this.createLines = function (){
for(var i=0,all=this.lAmount;i<all;i++){
this.lines[i] = new line();
}
},
this.addSpeed = function (){
// no error, but it's not executing addSpeed function
// if i write here a normal cycle like in createLines function
// it's working ok
this.linesCycle("addSpeed");
},
this.linesCycle = function(callFunction){
for(var i=0,all=this.lAmount;i<all;i++){
window['lineGroup.lines['+i+'].'+callFunction+'()'];
}
}
}
var line = function (){
this.addSpeed = function (){
console.log("works");
}
}
window['lineGroup.lines['+i+'].'+callFunction+'()'];
literally tries to access a property that starts with lineGroups.lines[0]. Such a property would only exist if you explicitly did window['lineGroups.lines[0]'] = ... which I'm sure you didn't.
There is no need to involve window at all. Just access the object's line property:
this.lines[i][callFunction]();
i get no error but the function is not executed.
Accessing a non-existing property doesn't generate errors. Example:
window[';dghfodstf0ap9sdufgpas9df']
This tries to access the property ;dghfodstf0ap9sdufgpas9df, but since it doesn't exist, this will result in undefined. Since nothing is done with the return value, no change can be observed.
Without a name space use:
window["functionName"](arguments);
SO wrap it up and use it thus:
cycle(someFunction);
function cycle(name){
for(var i=0;i<all;i++){
window[name](i);;
}
}
With a namespace, include that:
window["Namespace"]["myfunction"](i);
Note that this is likely a bit of overkill but using a function to make a class object (you can google the makeClass and why it is/could be useful) you can create instances of the object.
// makeClass - By Hubert Kauker (MIT Licensed)
// original by John Resig (MIT Licensed).
function makeClass() {
var isInternal;
return function (args) {
if (this instanceof arguments.callee) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
var instance = new arguments.callee(arguments);
isInternal = false;
return instance;
}
};
}
var line = function () {
this.addSpeed = function () {
console.log("works");
};
};
var LineGroup = makeClass();
LineGroup.prototype.init = function (lineNumber) {
this.lAmount = lineNumber?lineNumber:5,
this.lines = [],
this.createLines = function (mything) {
console.log(mything);
var i = 0;
for (; i < this.lAmount; i++) {
this.lines[i] = new line();
}
},
this.addSpeed = function () {
console.log("here");
this.linesCycle("addSpeed");
},
this.linesCycle = function (callFunction) {
console.log("called:" + callFunction);
var i = 0;
for (; i < this.lAmount; i++) {
this.lines[i][callFunction]();
}
};
};
var myLines = LineGroup();
myLines.createLines("createlines");
myLines.addSpeed();
//now add a new instance with 3 "lines"
var newLines = LineGroup(3);
newLines.createLines("createlines2")
console.log("addspeed is a:" + typeof newLines.addSpeed);
console.log("line count"+newLines.lAmount );
newLines.addSpeed();

How do I append a javascript-function to another javascript-function?

How can I define, that a javascript function is to be called, whenever another specific javascript function has been called and executed?
var UploadStatusController= {
var uploadedcount,
UpdateStatus: function (numberOfUploadedFiles) {
UploadStatusController.uploadedcount += numberOfUploadedFiles;
});
},
var DisplayController{
UpdateInfoBox: function () {
$('#Infobox').InnerHtml = UploadStatusController.uploadedcount;
});
}
I do not want to call my DisplayController from the UploadStatusController,
and I also do not want to pass my DisplayController into the UploadStatusController as a variable.
Instead, I am looking for a way to bind my function to calls on the other function in a way similar to binding it to a document-event.
var uploadStatusController = {};
(function () {
var subscribers = [];
var uploadedCount = 0;
uploadStatusController.updateStatus = function (numberOfUploadedFiles) {
uploadedCount += numberOfUploadedFiles;
// call subscribers
callSubscribers();
};
uploadStatusController.subscribe = function (fn) {
subscribers.push(fn);
};
function callSubscribers() {
for (var i = 0, len = subscribers.length; i < len; i++) {
subscribers[i].apply(this, [uploadedCount]);
}
};
}());
// subscribe to event from anywhere you need
uploadStatusController.subscribe(function (uploadedCount) {
console.log(uploadedCount);
});

Javascript class "Object has no method error"

I have a class called question . I am trying to call this display method from another class by creating its correspoding object. But I get this error. Will be glad if you can help me with this.
///////////////QUESTION///////////////
function Question(id, text){
this.id = id;
this.text = text;
}
function QType1(id, text, choices, answers){
//this is true or false
Question.call(this, id, text) ;
this.choices = choices;
this.answers = answers;
}
QType1.prototype = new Question();
//inherit Question
QType1.prototype.constructor = QType1;
QType1.Display = function(){
console.log("Display Question");
}
///////////////QUIZ//////////////////
function quiz(){}
quiz.prototype.SetHomeScreen = function(x,y){
var svgCanvas = CreateCanvas(x,y);
AddText(svgCanvas,100,50, quiz_input.Settings.Layout.Text);
console.log("Text Added");
start_but = AddStartButton(svgCanvas, 300, 250);
console.log("start button Added");
start_but
.on("click", function(d,i) {
startquiz();
});
var startquiz = function(){
console.log(this);
quiz.prototype.StartQuiz();
};
}
quiz.prototype.question_objs = [];
quiz.prototype.user_ans = [];
quiz.prototype.corr_ans = [];
quiz.prototype.LoadQuestions = function(){
for(var i=0, l=questions.length; i<l; i++){
this.question_objs.push(new QType1(questions[i].id, questions[i].settings.text, questions[i].settings.choices, questions[i].settings.answers));
}
console.log(this.question_objs);
}
quiz.prototype.DisplayQuestions = function(){
var i = 0;
var l = this.question_objs.length;
while(i < l){
console.log(this.question_objs[i] instanceof QType1);
this.question_objs[i].Display();
}
}
quiz.prototype.StartQuiz = function(){
quiz.prototype.LoadQuestions();
console.log("Starting Quiz");
quiz.prototype.DisplayQuestions();
}
The Error Message which I get is.
Thanks in Advance
Two possible causes:
you didn't declare function Qtype1() {} and
you didn't instatiate a qtype1 object like so var q = new Qtype1()
EDIT: you didn't make Display a method of QType1.
The only way you could have a QType1.Display method is if you had declared QType1 as a variable, like var QType1 = {}
That way you could have a Display method directly bound to the variable. But as you declared it as a constructor you need QType1.prototype.Display = function () { console.log('Display question...'); };
Also - your inheritance is a bit messy. You're calling Question.call(this, id, text) then you're declaring QType1.prototype = new Question() and then doing the same with the constructor. You need to review your javascript prototypal inheritance theory a bit.

Categories

Resources