var jsonObj = jQuery.parseJSON(passData);
thisId = jsonObj.id;
thisPage = jsonObj.page;
thisPageItem = jsonObj.item;
if (jsonObj.json != undefined) {
$.each(jsonObj.json, function (key, tempJson) {
if (tempJson.position != undefined) {
var tempId = tempJson.id;
var tempStyle = tempJson.position;
objJsonArr[tempId] = tempStyle;
}
});
}
for (var i = 1; i < 9; i++) {
var tempList = window.objJsonArr;
var tempDom = '#dropAbleArea #area.' + i;
$(tempDom).css('top', dropObjectPositionArr[i].top);
$(tempDom).css('left', dropObjectPositionArr[i].left);
console.log("Out " + objJsonArr[i]);
$(tempDom).load('images/pageThree/' + i + '.svg', null, function (e) {
console.log("In " + objJsonArr[i]);
});
}
$.each(objJsonArr, function (key, value) {
if (value != undefined) {
$('#dropAbleArea div#area').on('', function (e) {
$('#dropAbleArea div#area.' + key + ' g#ball path#bk').attr('style', value);
});
};
});
the return is
[Log] Out fill:rgb(244, 133, 142) (3.html, line 130)
[Log] Out fill:rgb(130, 202, 156) (3.html, line 130)
[Log] Out fill:rgb(207, 229, 174) (3.html, line 130)
[Log] Out fill:rgb(130, 202, 156) (3.html, line 130)
[Log] Out undefined (3.html, line 130, x4)
[Log] In undefined (3.html, line 132, x8)
Q1: I can't get the javascript array data in the console.log("In " + objJsonArr[i]);
Q2: How can i get the dynamic content in the
$('#dropAbleArea div#area').on('',function(e){
$('#dropAbleArea div#area.' + key +' g#ball path#bk').attr('style',value);
});
The complete function given to jQuery .load captures the variables objJsonArr and i. But when the function is executed, the loop has already finished and i has the value 9 and objJsonArr[9] seems to be undefined.
You can see the same effect with a delayed function
var a = [ 1, 2, 3 ];
for (var i = 0; i < a.length; ++i) {
setTimeout(function() {
console.log('a[' + i + ']=' + a[i]);
}, 500);
}
which gives the output
a[3]=undefined
JSFiddle
You can "fix" this with creating an additional scope by wrapping the anonymous function, where you capture the loop variable's value in a another variable k
var a = [ 1, 2, 3 ];
for (var i = 0; i < a.length; ++i) {
setTimeout((function(k, v) {
return function() {
console.log('a[' + k + ']=' + v);
};
})(i, a[i]), 500);
}
JSFiddle
In your case, this would be something like
$(tempDom).load('images/pageThree/' + i + '.svg', null, (function(v) {
return function (e) {
console.log("In " + v);
};
})(objJsonArr[i]));
Update:
I just learned about jQuery.proxy() and it seems to be the solution to your problem. Taking my first example and applying jQuery.proxy to it will give
var a = [ 1, 2, 3 ];
for (var i = 0; i < a.length; ++i) {
setTimeout($.proxy(function(k, v) {
console.log('a[' + k + ']=' + v);
}, null, i, a[i]), 500);
}
JSFiddle
This is equivalent to the closure in my second example, where the two values are captured. Equally, using $.proxy in your program will be
$(tempDom).load('images/pageThree/' + i + '.svg', null, $.proxy(function (v, e) {
console.log("In " + v);
}, null, objJsonArr[i]));
Related
I have a json file. I would like to write the content from it into two divs. If json.length % 2 === 0 then write in <div id="data1"> else write it in <div id="data2">.
I recieve the json file, but it only writes the 1st if sentence.
I hope the code will make more sense then I do =)
var data1 = document.getElementById("data1");
var data2 = document.getElementById("data2");
loadJSON(function(json) {
var l = Object.keys(json).length;
console.log("json start");
for (var i = 0; i <= l; i++){
console.log(i);
if (l % 2 === 0){
for (x in json) {
data1.innerHTML="<img src=" + json[x].picture + "/>";
data1.innerHTML+=json[x].price_thingy.price + json[x].price_thingy.suf;
console.log("0 " + l); // this never prints
}
} else {
for (x in json) {
data2.innerHTML="<img src=" + json[x].picture + "/>";
data2.innerHTML+=json[x].price_thingy.price + json[x].price_thingy.suf;
console.log("1 " + l); // this never prints
}
}
}
});
Edit 1:
So, I've changed l % 2 === 0 to i % 2 === 0 and added innerHTML += and things kind of work now. The problem now, is that I get everything two times. So basically I get the same picture and the price in both divs...
Any idea how I could solve this?
In your code you apppear to have made a typo.
When iterating over an array, your should use the index variable in this case.
Therefore the fix should be:
if (i % 2 === 0){
...
}
Instead of:
if (l % 2 === 0){
...
}
As an answer to your secondary problem:
You are looping through your json results twice.
Just reorder your code a little bit.
The result would be something like this:
loadJSON(function(json) {
console.log("json start");
var i = 0;
for (x in json){
console.log(i);
if (i % 2 === 0){
data1.innerHTML="<img src=" + json[x].picture + "/>";
data1.innerHTML+=json[x].price_thingy.price + json[x].price_thingy.suf;
console.log("0 " + l); // this never prints
} else {
data2.innerHTML="<img src=" + json[x].picture + "/>";
data2.innerHTML+=json[x].price_thingy.price + json[x].price_thingy.suf;
console.log("1 " + l); // this never prints
}
i++;
}
});
Hi there are multiple ways to accomplish what you are trying.
However I think that there are some typos like the l % 2.
L does not increase and is the item length of your json thats why I changed it in my snippet.
Now to simplify the code above and get the output I guess you want:
const data1 = document.getElementById("data1");
const data2 = document.getElementById("data2");
const json = {
a: { picture: 'linkA', price_thingy: { suf: '€', price: 1.99 } },
b: { picture: 'linkB', price_thingy: { suf: '$', price: 1.99 } },
c: { picture: 'linkC', price_thingy: { suf: '£', price: 1.99 } },
d: { picture: 'linkD', price_thingy: { suf: '¥', price: 1.99 } },
}
const l = Object.keys(json).length;
let i = 0;
for (key in json) {
const value = json[key];
if (i % 2) {
// With this as syntax you don't have to use +
data1.innerHTML += `<img src="${value.picture}"/>`;
data1.innerHTML += value.price_thingy.price + value.price_thingy.suf;
} else {
data2.innerHTML += `<img src="${value.picture}"/>`;
data2.innerHTML += value.price_thingy.price + value.price_thingy.suf;
}
i += 1;
}
<div id='data1'></div>
<div id='data2'></div>
I need to create a small delay in this for loop:
for (i = 1; i <= cloneIndex; i++) {
var myElem = document.getElementById('form' + i);
if (myElem != null) {
function postData() {
return {
udd: document.getElementById('udd').value,
data: date_in,
hora_ini: hour_in,
hora_fim: hour_out,
cat: $('#form' + i).find('select[id="cat"]').val(),
m1: $('#form' + i).find('select[id="q1"]').val(),
m2: $('#form' + i).find('select[id="q2"]').val(),
m3: $('#form' + i).find('select[id="q3"]').val(),
m4: $('#form' + i).find('select[id="q4"]').val(),
m5: $('#form' + i).find('select[id="q5"]').val()
}
}
var newItem = postData();
$2sxc(#Dnn.Module.ModuleID).webApi.post('app/auto/content/audits', {}, newItem);
}
}
Following stackoverflow examples, I tried this solution:
for (i = 1; i <= cloneIndex; i++) {
(function(i){
setTimeout(function(){
var myElem = document.getElementById('form' + i);
if (myElem != null) {
function postData() {
return {
udd: document.getElementById('udd').value,
data: date_in,
hora_ini: hour_in,
hora_fim: hour_out,
cat: $('#form' + i).find('select[id="cat"]').val(),
m1: $('#form' + i).find('select[id="q1"]').val(),
m2: $('#form' + i).find('select[id="q2"]').val(),
m3: $('#form' + i).find('select[id="q3"]').val(),
m4: $('#form' + i).find('select[id="q4"]').val(),
m5: $('#form' + i).find('select[id="q5"]').val()
}
}
var newItem = postData();
$2sxc(Dnn.Module.ModuleID).webApi.post('app/auto/content/audits', {}, newItem);
}
}, 1000 * i);
}(i));
}
However this breaks the function inside. It seems myElem is now always null. Too many "i"s? How can I fix this?
You need to define the variable inside the closure for it to be unique to each iteration:
for (var i = 1; i < 10; i++) {
(function() {
var k = i; // <-- k will be different for each iteration, because it was declared inside the closure. i was defined outside the closure.
setTimeout(function() {
console.log("Delayed: ", i, k)
}, i * 1000)
}());
}
...or else include i in the closure definition:
for (var i = 1; i < 10; i++) {
(function(i) {
setTimeout(function() {
console.log("Delayed: ", i)
}, i * 1000)
}(i));
}
Nevermind. The reason the code did not work was simple. The rest of the code below did not wait for the delayed loop to end, so it actually broke the function.
This fixed it (placed inside the setTimeout function):
k++;
if (k == cloneIndex) {rest of the code that needs the loop to end}
The code below works. The code calls an API to get historical trades (100 trades each time pér pull). Because there is an limit - how many and how often im allowed to call the API - the structure is like recursive.
The flow is like this:
Get the current MAX tradeId - which is stored in the DB.
Now make a new PULL with startIndex = MaxId and a length of 100 (to pull 100 new trades).
FIRST when the callback function is called the main code continues and 100 new trades are pulled... ect. ect.
So...
The code SHOULD behave like - Psydo-code
var maxId = GetMaxIdFromDB();
Pull(maxId, 100, callback);
function callback(){
... do different stuff..
maxId += 100;
Pull(maxId, 100, callback);
}
The strange thing and my question is: How can the API function "getProductTrades " be called more than one time - where my cursor variable contains the SAME value - when it is incremented with 100 (or the number of valid data elements each time).
I'm talking/ref. especially to the following lines:
wl.debug("getProductTrades - cursor: " + cursor + " Limit: " + limit);
publicClient.getProductTrades({'after': cursor, 'limit': limit}, callback);
The insertQuery.InsertMatchMsgArrayToDB(allData); method calls another DB method which returns a promise.
You can see a screenshot of the issue here:
http://screencast.com/t/DH8rz3UxnyZ
The real code is here:
pullTradesBetween: function (minTradeId, maxTradeId) {
var wl = new WinLog();
var tradeCounter = 0;
try {
var WebSocketEmit = new WSemitter();
var startTime = new Date().toLocaleString();
var executeTradePullAgain = null;
wl.debug("REST API START: " + startTime);
var cursor;
var incrementedCursorWith = 0;
if ((maxTradeId - minTradeId) < 100) {
cursor = maxTradeId + 1;
}
else
cursor = minTradeId + 100;
var callback = function (err, response, data) {
if (executeTradePullAgain !== null)
clearTimeout(executeTradePullAgain);
if (err)
wl.info("Err: " + err);
var validData = [];
incrementedCursorWith = 0;
if (response == null)
wl.info("RESPONSE ER NULL");
if (data !== null) {
for (var i = data.length - 1; i >= 0; i--) {
var obj = data[i];
var tradeId = parseInt(obj.trade_id);
if (obj !== null && (minTradeId <= tradeId && tradeId <= maxTradeId)) {
validData.push(data[i]);
}
}
if (validData.length == 0) {
wl.debug("Contains 0 elements!");
}
else {
cursor = cursor + validData.length;
incrementedCursorWith = validData.length;
insertDataToDB(validData);
}
}
else
wl.debug("DATA IS NULL!");
wl.debug("cursor: " + cursor + " maxTradeId: " + maxTradeId);
var diffToMax = maxTradeId - (cursor - incrementedCursorWith);
if (diffToMax >= 100)
pullTrades(cursor, 100); // 100 is default
else if (diffToMax >= 0)
pullTrades(maxTradeId + 1, diffToMax + 1); // X = Only the last trades in the given series of trades
else {
wl.info("REST API START: " + startTime + " REST API DONE: " + new Date().toLocaleString());
WebSocketEmit.syncHistoricalDataDone();
}
};
function pullTrades(cursor, limit) {
tradeCounter += limit;
if(tradeCounter % 10000 == 0){
wl.info('Downloaded: ' + tradeCounter + ' trades via REST API (Total: ' + cursor + ')');
}
pullTradesAgainIfServerDoesNotRespond(cursor, limit);
wl.debug("getProductTrades - cursor: " + cursor + " Limit: " + limit);
publicClient.getProductTrades({'after': cursor, 'limit': limit}, callback);
}
function pullTradesAgainIfServerDoesNotRespond(cursor, limit) {
executeTradePullAgain = setTimeout(function () {
wl.debug('pullTradesAgainIfServerDoesNotRespond called!');
pullTrades(cursor, limit);
}, 30000);
}
// SAVE DATA IN DB!
function insertDataToDB(allData) {
insertQuery.InsertMatchMsgArrayToDB(allData);
}
wl.debug("pull trades: " + cursor);
pullTrades(cursor, 100);
}
catch(err){
wl.info('pullTradesBetween: ' + err);
} }};
It happens when you get no data out of getProductionTrades.
If the data returned is null, you will never reach the lines
cursor = cursor + validData.length;
incrementedCursorWith = validData.length;
but you still call
pullTrades(cursor, 100);
at the end. I don't know if it's intended or an actual error so i leave the solution (should be trivial now) up to you.
I try to simplify your code
pullTradesBetween: function (minTradeId, maxTradeId) {
var WebSocketEmit = new WSemitter(); // try-catch ?
var curr = (maxTradeId - minTradeId < 100) ? maxTradeId + 1 : minTradeId + 100;
// function always return data or infinite error-loop
function getProductTrades (after, limit, callback) {
// try-catch ?
publicClient.getProductTrades ({after, limit}, function(err, data) {
if (err) {
console.log(err);
return getTrades(after, limit, callback);
}
callback(null, data);
});
}
function onDataReady (err, data) {
if (err)
throw new Error('Impossible!');
if (!data || !(data instanceof Array))
return ... smth on empty data ...
var validData = data.filter(function(obj) {
return obj &&
minTradeId <= parseInt(obj.trade_id) &&
parseInt(obj.trade_id) <= maxTradeId;
}).reverse();
if (validData.length == 0)
return ... smth on empty data ...
insertDataToDB(validData);
curr += validData.length; // maybe +-1
var remaining = maxTradeId - curr;
if (remainig == 0) {
console.log('Done');
// try-catch ?
WebSocketEmit.syncHistoricalDataDone();
}
return (remaining >= 100) ?
getProductTrades(curr, 100, onDataReady) :
getProductTrades(maxTradeId + 1, remaining + 1, onDataReady); // ??
}
getProductTrades(curr, 100, onDataReady);
}
I have a json file with a list of users and points. I want to somehow Loop through until the _id == userId, then count how many objects there are to get their position.
So far I have this json file which has the points in desc order already
[
{
"_id":"55db8684ce3bf55b4b612a72",
"firstname":"Billy",
"lastname":"Bob",
"points":3109373
},
{
"_id":"55dbdffeaba8ee274d3b9f89",
"firstname":"Steve",
"lastname":"Jones",
"points":34434
},
{
"_id":"55dbdbf756b0fa064dd3e507",
"firstname":"Jim",
"lastname":"Kirk",
"points":1000
},
{
"_id":"55dbdc2756b0fa064dd3e508",
"firstname":"Casey",
"lastname":"Jones",
"points":36
},
{
"_id":"55dbdbd656b0fa064dd3e506",
"firstname":"Reg",
"lastname":"Barclay",
"points":33
},
]
What I need to do is find the position for the user using their ID. So far I have but the position always returns undefined.
$.each(obj, function(index, value) {
var returnObj = (this === "<%= user._id %>");
var position = returnObj.length;
console.log('user position is ' + position);
});
But this always returns undefined 11 times, which is what the position should be.
If I got you right, using for instead of each works which is much faster and not much to code.
try this,
for(var i =0;i < obj.length; i++)
{
if(obj[i]['_id'] == "55dbdc2756b0fa064dd3e508"){
alert('position :' + parseInt(i + 1)); //<--position in an obj
alert('index :' + i); //<----actual index
break;
}
}
var obj=[
{
"_id":"55db8684ce3bf55b4b612a72",
"firstname":"Billy",
"lastname":"Bob",
"points":3109373
},
{
"_id":"55dbdffeaba8ee274d3b9f89",
"firstname":"Steve",
"lastname":"Jones",
"points":34434
},
{
"_id":"55dbdbf756b0fa064dd3e507",
"firstname":"Jim",
"lastname":"Kirk",
"points":1000
},
{
"_id":"55dbdc2756b0fa064dd3e508",
"firstname":"Casey",
"lastname":"Jones",
"points":36
},
{
"_id":"55dbdbd656b0fa064dd3e506",
"firstname":"Reg",
"lastname":"Barclay",
"points":33
},
]
for(var i =0;i < obj.length; i++)
{
if(obj[i]['_id'] == "55dbdc2756b0fa064dd3e508"){
alert('position :' + parseInt(i + 1));
alert('index :' + i);
break;
}
}
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;
}