Javascript Error - Undefined - javascript

I am trying to create a format for a graph. When I try to do so I am getting an undefined with console.log before the data. Here's my code
$(document).ready(function () {
var graphData = new Array();
$.getJSON("ds/js.json", function (Data) {
dataLength = returnedData.data.length;
var x = new Array();
var y = new Array();
var mytext, dataa, f;
for (i = 0; i < dataLength; i++) {
x[i] = Data.data[i].avgPrice;
y[i] = Data.data[i].numProducts;
}
for (var a = 0; a < 6; a++) {
mytext = "x:" + x[a] + "," + "y:" + y[a] + "}" + "," + "{";
dataa = dataa + mytext;
}
console.log(dataa);
var f =
"[{data : [{" + dataa;
console.log(f);
});
drawGraph(graphData);
});
Console output :
undefinedx:87.6,y:85},{x:116.08,y:61},{x:113.11,y:49},{x:181.37,y:65},{x:138.14,y:74},{x:66.03,y:89},x:66.03,y:89},{
What am I doing wrong here? And also I want a separate format for a=5, that stops the ", {" coming at the end.

When you do this:
for (var a=0;a<6;a++){
mytext = "x:" +x[a] + "," + "y:" +y[a] + "}" + "," + "{" ;
dataa=dataa+mytext;
}
you're performing string concatenation with dataa and mytext. However, in the first iteration of that for loop dataa has not yet been initialised, and the string representation of that is undefined.
When you declare the dataa variable initialise it as an empty string instead:
var mytext,dataa = '',f;
As an aside, it's important to remember that $.getJSON() makes an asynchronous request for data. If the result of that call is necessary for the drawGraph function to perform correctly then your code isn't going to function as you might expect (though with what you've posted in the question there's no definitive indication this is the case).
The $.getJSON() function will finish executing immediately (after initiating the request), allowing drawGraph to execute, but there's no guarantee that the request will have received a response and the processing of returnedData will have occurred; in fact there's a very strong possibility that won't have happened.

You shouldn't be building an object through string concatenation like that. I'd recommend actually building up an array of objects like so:
var dataa = [];
for (var a = 0; a < 6; a++) {
var newObj = {x: + x[a], y: + y[a]};
dataa.push(newObj);
}
And then to generate the f you currently have:
var f = JSON.stringify([{data: dataa}]);

dataa = dataa + mytext;
--------------^
this is undefined initially
You need to do this -
var mytext, dataa = "", f;

Related

Javascript for loop within function not pushing to array

EDIT - code to calculate refill_playlist_len included
I have a function in Javascript that deletes a row of an HTML table and populates it again with values from arrays.
Within this deleteRow function, I have a for loop which loops through a string and assigns parts of the strings to different variables and tries to push them onto arrays.
Without the for loop, it works fine (i.e. when I just index manually) but for some reason when I place it in a for loop, the values aren't pushed onto the arrays. The values themselves print fine on each iteration they just aren't added to the array.
Refill_playlist_len is the count of the Django Queryset (30).
var refill_playlist_len = '{{ playlist.count }}';
var artist_Arr = [];
var track_Arr = [];
var track_id_Arr = [];
var album_Arr = [];
var artist_name;
var track_name;
var track_id;
var album_name;
for (var i = 0; i < refill_playlist_len; i++) {
var searchStr = refill_playlist[i];
console.log(searchStr);
console.log(typeof searchStr);
console.log(typeof refill_playlist);
//grab variables
artist_name = searchStr.match(new RegExp("artist_name:" + "(.*)" + ", album_name:"));
console.log(artist_name[1]);
artist_Arr.push(artist_name[1]);
track_name = searchStr.match(new RegExp("track_name:" + "(.*)" + ", acousticness:"));
console.log(track_name[1]);
track_Arr.push(track_name[1]);
track_id = searchStr.match(new RegExp("track_id:" + "(.*)" + ", track_name:"));
console.log(track_id[1]);
track_id_Arr.push(track_id[1]);
album_name = searchStr.match(new RegExp("album_name:" + "(.*)" + ", track_number:"));
console.log(album_name[1]);
album_Arr.push(album_name[1]);
}
The console logs are in the image below. You can see part of the 'searchStr' printed, along with the data types, artist name, track IDs, etc but for some reason, it says that 'searchStr' is undefined?
Console
I'm quite new to Javascript so my apologies if there is something basic I'm forgetting.
Multiple issues with code. Please clean up code. Sample is given below.
function find(refill_playlist) {
const refill_playlist_len = refill_playlist.length
let artist_Arr = []
let track_id_Arr = []
let track_Arr = []
let album_Arr = []
for (i = 0; i < refill_playlist_len; i++) {
var searchStr = refill_playlist[i];
if(!searchStr) continue;
//grab variables
artist_name = searchStr.match(/artist_name:(.*), album_name:/);
artist_name && artist_Arr.push(artist_name[1]);
track_name = searchStr.match(/track_name:(.*), acousticness:/);
track_name && track_Arr.push(track_name[1]);
track_id = searchStr.match(/track_id:(.*), track_name:/);
track_id && track_id_Arr.push(track_id[1]);
album_name = searchStr.match(/album_name:(.*), track_number:/);
album_name && album_Arr.push(album_name[1]);
}
console.log(artist_Arr)
console.log(track_id_Arr)
console.log(track_Arr)
console.log(album_Arr)
}
find(
[
`
artist_name: test, album_name:
`,
null
]
)

How can I stringify output from a for loop?

I have the following for loop and I would like the output of the loop to be stringified into a query string as shown in the desired output below. I'm using the qs npm package for stringifying URLs.
What's the best way of going about getting the desired output?
for (i = 0; i < 2; i++) {
var foo = "pr" + [i] + "va";
var bar = "value";
};
//Desired output: ?pr0va=value&pr1va=value
Instead of creating variables - create String and do concatenation in every loop.
Check my code snippet.
var query = "";
var size = 2;
for (i = 0; i < size; i++) {
query += "pr" + [i] + "va=value";
if (i+1<size)
query += "&";
};
console.log(query);
This should work for you.
function test () {
var i =0;
var arr = [];
for(i=0;i<2;i++) {
arr.push( "pr" + [i] + "va=value" );
}
console.log('?' + arr.join('&').toString())
}
Something like this?
var output = '?';
for (i = 0; i < 2; i++) {
var foo = "pr" + [i] + "va";
var bar = "value";
output += foo + "=" + bar + "&";
};
console.log(output);
//Desired output: ?pr0va=value&pr1va=value
You can do it like this.
var output = "?";
for (i = 0; i < 2; i++) {
output += "pr" + [i] + "va=value&";
};
console.log(output.slice(0, -1))
If I were to review such code I would prefer to see the following:
Avoid concatenation.
Use of functional programming.
Reasonable usage of 3rd parties - so yes for querystring
All of those are for readability, simplicity and maintainability benefits. And I admit it is arguable.. so please don't argue :)
I will use your code as a baseline and improve from there
for (i = 0; i < 2; i++) {
var foo = "pr" + [i] + "va";
var bar = "value";
};
Note that your snippet is incomplete, and so, at the beginning mine will not be complete too, but I'll get there
Avoid concatenation
I will avoid concatenation using template literal
for (i = 0; i < 2; i++) {
`pr${i}va=value`;
};
Use of functional programming
I will iterate over numbers using an array, and reduce to construct an object
const queryParams = Array(2).fill().reduce((object, value, index) => {
object[`pr${index}va`] = 'value';
return object;
} , {} )
Using 3rd parties
Now I will use querystring to turn queryParams to a query string
return querystring.stringify(queryParams);
All together now
/**
* #param {number} count - number of query parameters to generate
* #returns {string} query string. for example for count=2 will return `pr1va=value&pr2va=value`
**/
function generateQueryString(count=2){
const queryParams = Array(count).fill().reduce((object, value, index) => { // convert N number to key-value map using reduce
object[`pr${index}va`] = 'value';
return object;
} , {} );
return querystring.stringify(queryParams);
}
You can create an array of size, loop and then join it:
function createString(size) {
return new Array(size).fill(0).map((v, i) => {
return "pr" + i + "va=value";
}).join("&");
}
console.log(createString(2));

Can't get objects inside of array

I have been trying to use JavaScript array to push my object by header
like this :
var tab_temp = new Y.TabView(
{ srcNode: '#' + tabId }
);
tabsArray['"' + type + "_" + subTypes + '"'] = tab_temp;
Let's type = "x" and subTypes = "y", so I was expecting the object when I write something like:
tabs["x_y"]
But there is problem with this. When I debug, I can see this array will hold an object "x_y" but length of the array is 0
I can't use push also because in that way I need to use index to get it back but it is tough since sequence might change.
Edit 1:
I am using this because I want to hold a couple of TabView objects. Otherwise I can't reach those object after they created. (AlloyUI). I was able to push those object inside of array. As you see "Baru_BARANG" include and object that start with: s
Edit 2:
Thanks for help, I fixed it. I used Object instead of Array for this:
var tabs = {}
tabs[x + "_" + y] = "z";
I get the value by tabs[x + "_" + y]
You really need to be reading more about working with objects in JavaScript.
Try here first.
var type = "x";
var subType = "y";
var tabsArray = {};
tabsArray[type + "_" + subType] = "z";
console.log("tabsArray = ");
console.log(tabsArray);
console.log("tabsArray['x_y'] = " + tabsArray["x_y"]); // output: z
// Including code added to question as a comment:
var tabsArray = [];
var x = "x";
var y = "y";
tabsArray[x + "_" + y] = "z";
console.log("tabsArray['x_y'] = " + tabsArray["x_y"]);
// tabsArray.length will still be 0. To set .length you can use:
for (var i = 0; i < tabsArray.length; i++) {
tabsArray.length = ++i;
};
console.log("tabsArray.length = " + tabsArray.length);
You are most likely instantiating tabsArray as an array, i.e. var tabsArray = [];. This results in the observed behavior.
Since you want to define the keys yourself, you should instantiate it as an object instead:
var tabsArray = {};
tabsArray['x_y'] = 'z';
More about working with objects in JavaScript.

Javascript: Reversing the loop ouput

Basically i'm creating a script to display the place value for set of numbers. Here's my script:
var arrn = '3252';
var temp = 0;
var q = arrn.length;
var j = 0;
for (var i = q-1; i >= 0; i--,j++) {
if (j!=0) temp = temp + ' + ';
{
temp += arrn[i] * Math.pow(10, j);
}
}
alert(temp);
My goal is to achieve 3000 + 200 + 50 + 2. But i get 2 + 50 + 200 + 3000. I tried temp.reverse() & sort functions but doesn't seem to work. Please help
Change
if(j!=0)temp=temp +' + ';
{
temp +=arrn[i]*Math.pow(10,j);
}
to
if(j!=0) {
temp=' + ' + temp;
}
temp = arrn[i]*Math.pow(10,j) + temp;
Live Example
Side note: Your braces in the first code block above are very misleading. What you have:
if(j!=0)temp=temp +' + ';
{
temp +=arrn[i]*Math.pow(10,j);
}
is
if(j!=0)temp=temp +' + ';
temp +=arrn[i]*Math.pow(10,j);
which is to say
if(j!=0) {
temp=temp +' + ';
}
temp +=arrn[i]*Math.pow(10,j);
the block in your version is not associated with the if, it's just a freestanding block.
Side note #2: Since you're using temp as a string everywhere else, I would initialize it with '' rather than with 0. Example The reason your string didn't end up with an extraneous 0 was really quite obscure. :-)
Just add the number to the beginning of the string instead of at the end:
for (var i = q - 1; i >= 0; i--, j++) {
if (j != 0) {
temp = ' + ' + temp;
}
temp = arrn[i] * Math.pow(10, j) + temp;
}
Demo: http://jsfiddle.net/Guffa/rh9oso3f/
Side note: You are using some confusing brackets in your code after the if statement. As there is a statement following the if statement, the brackets starting on the next line becomes just a code block, but it's easy to think that it's supposed to be the code that is executed when the condition in the if statement is true.
Another side note: the language attribute for the script tag was deprecated many years ago. Use type="text/javascript" if you want to specify the language.
How about temp.split("+").reverse().join(" + ")?
You can do this way. I know it can be optimised. But it works
var arrn='3252';
var temp=0;
var q=arrn.length;
var res = [];
var j=0;
for(var i=q-1;i>=0;i--,j++)
{
temp += parseFloat(arrn[i])*Math.pow(10,j);
res.push(arrn[i]*Math.pow(10,j));
}
res.reverse();
alert(res.join('+') + " = " + temp);
http://jsfiddle.net/he7p8y5m/
var arrn='3252';
var temp=new Array();
var q=arrn.length;
for(var i=0;i<=q-1; i++){
temp.push(arrn[i]*Math.pow(10,(q-i-1)));
}
temp = temp.join('+');
alert(temp);

Cannot read properly "split"

I have this piece of code in javascript:
var i = 0;
var j = 0;
while (allTextLines.length) {
var line = allTextLines.shift().split('"');
var temp = line[1].split('');
if (i == 0) {
alert(temp);
i++;
}
var x = (temp[0] + temp[1]+ temp[2] + temp[3] + "-" + temp[4] + temp[5] + temp[6]);
var y = line[3];
var z = line[5];
var g = line[7];
lines[j] = (x + ", " + z + ", " + g);
j++;
}
And it's happening something really weird. When i==0, it alerts temp and its split. After that I'm getting:
Uncaught TypeError: Cannot read property 'split' of undefined
If I remove the if, I will have this error right on the start. But if I do something like this:
var line = allTextLines.shift().split('"');
var temp = line[1].split('');
alert(temp);
var x = (temp[0] + temp[1]+ temp[2] + temp[3] + "-" + temp[4] + temp[5] + temp[6]);
It has no problem splitting (also the alert shows that it has been correctly split). The only problem is that I will have to click "ok" 5600 times. I don't understand what the hell is going on and why I am having this error.
I'm splitting a CSV file with lines like this:
35105,201401,503781827,"8400258","Faro","Lagoa (Algarve)","Portugal"
and I'm trying to add an '-' in here: "8400258", so it becomes "8400-258"
var line = allTextLines.shift().split('"');
var temp = line[1].split('');
Won't that fail when allTextLines only has one element in it, since the array is zero-based? I think you'd need to change the line[x] param to 0:
var temp = line[0].split('');
Might I suggest a different approach?
var line = allTextLines.shift().split(',');
var x = line[3].replace(/^"(\d{4})(\d{3})"$/, "$1-$2");
var y = line[4];
var z = line[5];
var g = line[6];
If you can trust that the format of the data is always the same, it's much less complex to do a pattern based replace than splitting a string like an array and re-assembling it.

Categories