Setting a variable after a successful ajax call - javascript

In java you can reference an outer class by stating its name followed by this.
class A {
void A() {
}
class B {
void B() {
A.this.A();
}
}
}
Now I am attempting to do something similar in javascript. Bellow I have constructor that makes an ajax call. This ajax call if successful sets the get method and the assets of the AssetManager.
function AssetManager(path) {
this.assets = {};
this.get = function(tag,name) {
return 0;
};
$.ajax({
url: path,
dataType: 'json',
success: function(o) {
if (o.sprite) {
var keys = Object.keys(o.sprite);
for (var i = 0; i < keys.length; i++) {
var obj1 = keys[i];
AssetManager.this.assets.sprite[obj1] = new Image();
AssetManager.this.assets.sprite[obj1].src = o.sprite[obj1];
}
}
AssetManager.this.get = function (tag, name) {
return assets[tag][name];
}
}
});
}

You have to create variable and point it to this prior executing ajax and access it within success handler:
function AssetManager(path) {
// ......
// Set this object to me variable
var me = this;
$.ajax({
url: path,
dataType: 'json',
success: function(o) {
if (o.sprite) {
var keys = Object.keys(o.sprite);
for (var i = 0; i < keys.length; i++) {
var obj1 = keys[i];
me.assets.sprite[obj1] = new Image();
me.assets.sprite[obj1].src = o.sprite[obj1];
}
}
me.get = function (tag, name) {
return assets[tag][name];
}
}
});

Assumming that your ajax call is suppose to lazyly initialize other properties of your AssetManager, you need to save the reference of this so that it can be used inside ajax method (where the meaning of this will change)
function AssetManager(path) {
this.assets = {};
this.get = function(tag,name) {
return 0;
};
var self = this;
$.ajax({
url: path,
dataType: 'json',
success: function(o) {
if (o.sprite) {
var keys = Object.keys(o.sprite);
for (var i = 0; i < keys.length; i++) {
var obj1 = keys[i];
self.assets.sprite[obj1] = new Image();
self.assets.sprite[obj1].src = o.sprite[obj1];
}
}
self.get = function (tag, name) {
return assets[tag][name];
}
}
});
}

Related

making multiple ajax calls within a for loop

I'm a relative newbie to javascript and I'm trying to make multiple ajax calls within a for loop. It loops through the elements of an array using a different url for an ajax call each time it goes through the loop. The problem is that the value of the variable 'test' is always equal to "condition4". I'm used to other languages where the value of 'test' would be "condition1", then "condition2" etc as it goes through the for loop. Here is a simplified version of my code:
var myData = [];
var cnt = 0;
var link;
var myCounter = 0;
var myArray = ["condition1", "condition2", "condition3", "condition4"];
for (x = 0; x < myArray.length; x++) {
link = "https://test.com/" + myArray[x];
myCounter = x;
GetJSON(function (results) {
for (i = 0; i < results.data.length; i++) {
var id = results.data[i].identifier;
var test = myArray[myCounter];
myData[cnt] = { "id": id, "test": test };
cnt++;
}
});
}
function GetJSON(callback) {
$.ajax({
url: link,
type: 'GET',
dataType: 'json',
success: function (results) {
callback(results);
}
});
}
I think you can solve this issue by sending and receiving myCounter value to server
for (x = 0; x < myArray.length; x++) {
link = "https://test.com/" + myArray[x];
myCounter = x;
$.ajax({
url: link,
type: 'GET',
dataType: 'json',
data: { myCounter: myCounter}
success: function(results) {
for (i = 0; i < results.data.length; i++) {
var id = results.data[i].identifier;
var test = results.data[i].myCounter
myData[cnt] = {
"id": id,
"test": test
};
cnt++;
}
}
});
}
When you are executing the loop, it attaches the myCounter reference. Then, due to the async task, when it finishes and call 'myCounter', it has already achieved the number 4. So, when it call 'myCounter', it is 4. To isolate the scope, you need to create a new scope every iteration and isolating each value of 'myCounter'
for (x = 0; x < myArray.length; x++) {
link = "https://test.com/" + myArray[x];
myCounter = x;
//IIFE
(function() {
var ownCounter = myCounter; //Isolating counter
GetJSON(function (results) {
for (i = 0; i < results.data.length; i++) {
var id = results.data[i].identifier;
var test = myArray[ownCounter];
myData[cnt] = { "id": id, "test": test };
cnt++;
}
});
})();
}
Or...
for (let x = 0; x < myArray.length; x++) {
link = "https://test.com/" + myArray[x];
myCounter = x;
GetJSON(function (results) {
for (i = 0; i < results.data.length; i++) {
var id = results.data[i].identifier;
var test = myArray[x];
myData[cnt] = { "id": id, "test": test };
cnt++;
}
});
}

Javascript OOP private functions

I would like to create a constructor which can be instantiated with a json file which then is used by some private functions which in the end pass their results to a public function of the prototype. Is this the right approach?
Here more specific code:
//constructor
function queryArray(json){
this.json = json;
//init qry template with default values
function qryInit() {
var qryTemplate = {
//some stuff
}
return qryTemplate;
}
//generate array of request templates
function qryTempArray(json){
var template = qryInit();
var qryTempArray1 = [];
for(var i = 0; i < json.length; i++){
qryTempArray1.push({
'SearchIndex': json[i].SearchIndex,
'Title': json[i].Title,
'Keywords': json[i].Keywords,
'MinimumPrice': json[i].MinimumPrice,
'MaximumPrice': json[i].MaximumPrice,
'ResponseGroup': template.ResponseGroup,
'sort': template.sort
});
}
return qryTempArray1;
}
}
//function for finally building all the queries
queryArray.prototype.qryBuilder = function(){
var qryTempArray1 = [];
qryTempArray1 = qryTempArray(this.json);
//other stuff
}
If I call the qryBuilder function on an Object, I get an error
in the function qryTempArray at the json.length in the for loop (undefined).
Why that?
As the code is written above, I'm surprised you even get to the loop. It would seem you'd get undefined when you called qryBuilder();
I would expect something along the lines of the following to work.
//constructor
function queryArray(json) {
var self = this;
self.json = json;
//init qry template with default values
self.qryInit = function() {
var qryTemplate = {
//some stuff
}
return qryTemplate;
}
//generate array of request templates
self.qryTempArray = function(json) {
var template = self.qryInit();
var qryTempArray1 = [];
for (var i = 0; i < json.length; i++) {
qryTempArray1.push({
'SearchIndex': json[i].SearchIndex,
'Title': json[i].Title,
'Keywords': json[i].Keywords,
'MinimumPrice': json[i].MinimumPrice,
'MaximumPrice': json[i].MaximumPrice,
'ResponseGroup': template.ResponseGroup,
'sort': template.sort
});
}
return qryTempArray1;
}
return self;
}
queryArray.prototype.qryBuilder = function() {
var qryTempArray1 = [];
qryTempArray1 = this.qryTempArray(this.json);
return qryTempArray1;
}
var q = new queryArray([{
'SearchIndex': 0,
'Title': 'foo',
'Keywords': 'testing',
'MinimumPrice': 20,
'MaximumPrice': 40
}]);
console.log(q);
console.log(q.qryBuilder());

Adding loop to ajax parameters

I'm looking to dynamically add properties and values to my ajax parameters, does anybody know how to do this? I can't seem to figure out how to accomplish this task. Thanks
doLookup = function($field, url, query, process, filterIdArray) {
$field.addClass("ajax-wait");
return ajax(url, {
parameters: {
"t:input": query,
"t:inputFilter": $filterField.val(),
for (var i = 0; i < filterIdArray.length; i++) {
"t:inputFilter_" + i : $("#" + myStringArray[i]);
},
},
success: function(response) {
$field.removeClass("ajax-wait");
return process(response.json.matches);
}
});
};
Create parameters outside the ajax function like:
params = {};
params["t:input"] = query;
params["t:inputFilter"] = $filterField.val();
for (var i = 0; i < filterIdArray.length; i++) {
params["t:inputFilter_" + i] = $("#" + myStringArray[i]);
}
return ajax(url, {
parameters: params,
success: function(response) {
$field.removeClass("ajax-wait");
return process(response.json.matches);
}
});
};

How can I iterate over this Javascript object?

I have the object:
var IOBreadcrumb = function () {
this.breadcrumbs = [];
this.add = function(title, url) {
var crumb = {
title: title,
url:url
};
this.breadcrumbs.push(crumb);
};
};
Lets say I add 3 items to breadcrumbs:
IOBreadcrumb.add('a',a);
IOBreadcrumb.add('b',b);
IOBreadcrumb.add('c',c);
How can I iterate over this and print out the title, and the url?
You could add an each method:
var IOBreadcrumb = function IOBreadcrumb() {
this.breadcrumbs = [];
this.add = function(title, url) {
var crumb = {
title: title,
url:url
};
this.breadcrumbs.push(crumb);
};
this.each = function(callback) {
for (var i = 0; i < this.breadcrumbs.length; i++) {
callback(this.breadcrumbs[i]);
}
}
};
And use it like this:
var ioBc = new IOBreadcrumb();
ioBc.add('a',a);
ioBc.add('b',b);
ioBc.add('c',c);
ioBc.each(function(item) {
console.log(item.title + ' ' + item.url);
});
add a method
print = function(){
for (var i = 0; i < this.breadcrumbs.length; i++) {
var current = this.breadcrumbs[i];
console.log(current.title, current.url);
}
}
to your IOBreadcrumb object, and then just invoke it
IOBreadcrumb.print();
Jason's answer is almost there. The only improvement is that there is no need to implement your own each function if you're using jquery.
var ioBc = new IOBreadcrumb();
ioBc.add('a',a);
ioBc.add('b',b);
ioBc.add('c',c);
$.each(ioBc.breadcrumbs, function(item) {
console.log(item.title + ' ' + item.url);
});
At the very least you should use $.each from your each function if you don't want callers to access breadcrumbs directly
...
this.each = function(callback) {
$.each(this.breadcrumbs, callback);
}
...

Javascript - Array of 'classes'

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.

Categories

Resources