I use promises in angular to get some data from the server. In promises success I do
promise.success(function (data, status) {
for (i = 0; i <= data.data.length; i++){
$scope.anArray[i] = data.data[i][1] ;
}
}
I do this because data that came from the server have this structure
{"result":"answered","data":[["jake","508"],["amir","602"],["ben","450"]]}
and I ONLY want to get the numbers 508 , 602 and 450. But I always get the same error TypeError: Cannot read property '0' of undefined reffering to this line : $scope.anArray[i] = data.data[i][0] ;.
Those numbers are feeded to a library to create a chart. Sometimes the chart is created, some times is not. Even if it is created, the same error is always there.
I dont know how to fix that error and getting the chart to be always created without any problems. Looks like the code doesnt like the data.data[i][0] structure, having a simple array like data.data[i] doesnt create an error.
What should I do?
Thanks
Your for loop has an extra execution. You've initialized i to 0 but you've also used <= which means you are going to execute on array[array.length] which is out of bonds. That returns undefined and when you try to access the [0] index on that undefined you get that error.
Change to
for (i = 0; i < data.data.length; i++){
If you're able to do assignment personally I would go with
$scope.anArray = data.data.map(entry => entry[1]);
and skip the for loop entirely. Note if you want to avoid lambdas this would be
$scope.anArray = data.data.map(function(entry) { return entry[1]; });
Related
I'm new to using JDBC and am learning how to use batch processing. After wasting a lot of time trying to figure out why my combination of JavaScript and SQL stored procs didn't work, I think I learned that you have to use one prepareCall when using addBatch and executeBatch. Is this true? If so, why?
To exemplify, here's some example input:
var vals = [["value1_1","value2_1","value3","value4","value5","value6_1"],
["value1_2","value2_2","value3","value4","value5","value6_2"]]
The below loop works as expected. Note that I prepareCall before entering the loop.
params = Array(vals.length).fill("?")
pstmt = conn.prepareCall("{call "+storedProcedure+"("+params+")}");
for (var i = 0; i < vals.length; i++) { // for each array
for (var j = 0; j < vals[i].length; j++) { // for each value within each array
// set the string
pstmt.setString(j+1, vals[i][j]);
}
pstmt.addBatch();
}
try {
pstmt.executeBatch();
} catch (err) {
//my err msg code
pstmt.close();
conn.close();
}
Now, sometimes I have records that have a different number of parameters so I thought that I could just move prepareCall into the first loop so that I can change the number of parameters as needed for each input array.
for (var i = 0; i < vals.length; i++) { // for each array
// moved prepareCall here
params = Array(vals.length).fill("?")
pstmt = conn.prepareCall("{call "+storedProcedure+"("+params+")}");
for (var j = 0; j < vals[i].length; j++) { // for each value within each array
// set the string
pstmt.setString(j+1, vals[i][j]);
}
pstmt.addBatch();
}
try {
pstmt.executeBatch();
} catch (err) {
//my err msg code
pstmt.close();
conn.close();
}
For this second loop, I don't get any errors from Javascript but I get a foreign constraint error from my stored proc. My stored proc makes a set of CALLs to create records based on the value of the last parameter. I understand that the error that I get is telling me that one of the FKs doesn't exist. This would only happen if the wrong set of CALLs was invoked or the right set of CALLs was invoked but one of the CALLs failed. I'm sure neither is the issue since the first loop works as expected.
Thus, I'm interested to learn why I have to use one prepareCall when I executeBatch? To confirm, I have to use totally separate prepareCalls when I have call different stored procedures with different numbers of parameters?
I don't think it matters but for good measure: I'm using MySQL 5.7.
The method prepareCall returns a CallableStatement object that is compiled for the specific statement that you passed to prepareCall. When you call addBatch, the set of parameters is added to that specific instance of CallableStatement. If you execute prepareCall again, you get a different CallableStatement handle, with its own batch.
So, in your second piece of code in each iteration of the outer loop, you create a new CallableStatement, losing the previous callable statement and its batch (creating a memory leak as well in your code and possibly in your DBMS). As a result, when you call executeBatch, you will only execute the last statement you prepared, with only a single set of parameter values.
If you need to execute distinct statement texts, you will need to prepare and execute them in order, and you cannot use batch(*).
* - You could use batch if multiple sets of parameters use the same statement text, but if there are order dependencies between different statement texts, this might get tricky
I'm working on a small project where I try to load some stuff from LocalStorage and append it to my html page.
here's what it looks like:
function fetchList() {
var list = JSON.parse(localStorage.getItem('list'));
var listList = document.getElementById('listList');
for (var i = 0; i < list.length; i++) {
.....stuff
}
I have it set so that I call this function in my body tag
<body onload="fetchList()">
I currently have nothing saved in local storage and it's giving me an error on the FOR loop statement, especially .length. I understand there's nothing there, but wouldn't it just skip to end of loop ?
instead it give sme this error:
Uncaught TypeError: Cannot read property 'Length' of null
Is there a reason why this wouldn't work? What am I doing wrong?
If there's nothing in storage yet, JSON.parse() will return null.
So then var list will also be null.
And null does not have a length property, explaining your error, since a for loop based around the length of something needs that length to be a number.
Try detecting the existance of the JSON string first:
var storedJSON = localStorage.getItem('list');
if ( storedJSON ) {
var list = JSON.parse( storedJSON );
// continue code
}
I think you'll have to check if null first
if (variable == null){
// your code here.
}
How to loop through this data: (I have no control over format)
{"rowCount":3,"1":{"K":"2009","V":"Some Data"},"2":{"K":"2010","V":"More Data"}}
Above is a console.log(results) and results is a string
var r = JSON.parse(results);
var t;
for(var i=1;i<=r.rowCount;i++) {
t=r[i].V;
tableData.push(
{title:t, year:'2009', hasChild:true, color: '#000'}
);
}
Error: TypeError: 'undefined' is not an object (evaluating 'r[i].V')
I cannot get it to evaluate the variable i. What am I doing wrong?
Thanks
UPDATE
The incoming data had a bad rowcount causing the error. The accepted answer however is correct... just user error on my part not catching the bad incoming data. Had I put a console.log inside the loop I would have realized the error was actually happening after two successful loops. oops
I assume r.rowCount should be j.rowCount.
Ideally you should also initialise the i variable if you haven't already (i.e. with the var keyword).
(I've also moved the var t declaration outside the loop, to make it clear that it's the same t throughout and you're just changing its value. You shouldn't redeclare it with var each time – although I doubt this affects the output.)
var j = {"rowCount":2,"1":{"K":"name","V":"john"},"2":{"K":"name","V":"sue"}};
var t;
for (var i = 1; i <= j.rowCount; i++) {
t = j[i].V;
console.log(t);
}
Working demo – JSFiddle
I'm making an HTML5 game and thinking 15 levels for it. I have an levels class that include level objects. This is the code part of it.
function levels(){
this.allLevels=[];
for (var i = 1; i <=15; i++) {
this.allLevels[this.allLevels.length]=new level(); //LEVEL OBJECTS CREATED INTO OBJECT
this.allLevels[this.allLevels.length-1].levelNumber=i; //LEVEL NUMBERS ARE SET
(i==1)? this.allLevels[this.allLevels.length-1].state='ZERO':this.allLevels[this.allLevels.length-1].state='LOCKED'; //LEVEL STATES ARE SET
}
}
As you might see, I have an allLevels array to keep the level information. So far so good everything works. After creating this class I added init and draw methods to this class. Here it is;
levels.prototype.initAll = function(){
for(var i=0;i<=15;i++){
this.allLevels[i].initAllCoor();
}
};
levels.prototype.draw=function(){
this.cleanCanvas();
for(var i=0;i<=15;i++){
this.allLevels[i].drawLevelIcon();
}
};
levels.prototype.cleanCanvas=function(){
ctxCanvasLevels.clearRect(0,0,800,570);
};
It has just three methods for now. The functions you see(initAllCoor and drawLevelIcon) are the level object's methods. When I called these methods, everything works.
You can say if everything works what are you asking. Although everything works smoothly, I'm getting error at the Chrome's console.
Uncaught TypeError: Cannot call method 'initAllCoor' of undefined
Uncaught TypeError: Cannot call method 'drawLevelIcon' of undefined
I can't understand, it says 'cannot call' but it does. Because of this errors I can't use console.log function, too.
When you create the levels:
for (var i = 1; i <=15; i++) {
In the "initAll" function:
for(var i=0;i<=15;i++){
There is never a level 0, yet the "initAll" function expects one.
It's not invalid or wrong, but it's somewhat weird to start filling a JavaScript array at position 1 instead of 0.
what is wrong with this below code ?
why it is printing size of array as zero?
function test() {
var arr = [];
for(var i = 0; i < 10; i++)
{
console.log('i ->' + i);
arr.push[i];
}
console.log('\n' + 'array length :' + arr.length);
}
--
Output:
i ->0
i ->1
i ->2
i ->3
i ->4
i ->5
i ->6
i ->7
i ->8
i ->9
array length :0
--
it is printing as zero(0)
push is a function.
You need to write arr.push(i) and not arr.push[i]. What you're doing in the latter is referring to arr.push as if it were an array, and then trying to access its ith subscript (or assuming that push is an object and trying to access a property that has the same value of i); it's effectively the same as writing a single line statement like so:
someArray[i];
Which doesn't really do anything.
Note: I have been bitten by this silly bug many times as well when I type too fast. ;)
Because .push[i] should be .push(i).
The reason you didn't get an error is that functions are objects in JavaScript, so you can legally get and set properties on functions.
What you were doing was fetching the the i property from the Array.prototype.push method (which will be undefiend).
console.log(arr.push[i]); // undefined
Probably worth noting that jsHint would catch this for you.