Getting NaN Error and undefined Error - javascript

I have a Problem with my push function in JavaScript.
<script type="text/javascript">
var myArr = []
var len = myArr.length
$.getJSON('daten.json', function(data) {
$.each(data,function(key,value) {
for(var i = 0; i <= len; i++){
myArr.push("<p>" + value.Name+i ," ", value.Nachname+i + "</p>")
}
})
$('.content').html(myArr.join(''))
})
</script>
I need to convert value.Name+i like this = value.Name0, value.Name1 and so on. I got a JSON File and the Keys are Dynamic, so the first entry got Name0 the second Name1 and so on. Now I must print the JSON file on my html page, but how I can write this line:
myArr.push("<p>" + value.Name+i ," ", value.Nachname+i + "</p>")
with my var i which increment in the loop, to call the Keys in my JSON file?
Like value.Name0. Doing value.Name+i and value.Name.i does not work.

It seems to me what you're looking for is something like this:
myArr.push("<p>" + value['Name'+i] ," ", value['Nachname'+i] + "</p>")
This portion of javascript is covered pretty nicely here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

Take the object property in a variable, use condition to check if it has value or not then concat it
var nameval = value.name;
then use in your javascript variable
nameval+i

You need to convert your i (integer value) to string prior to adding it.
use:
value.Name + i.toString()
here's the jfiddle link: http://jsfiddle.net/kpqmp49o/

Related

What am I receiving undefined when building this string? Javascript

I"m attempting to build a string in order to put the results in a DataTables table.
I'm taking an array and using regex to get everything in it's own index and my resultant string array is this:
["41.8059016", "-77.0727825", "School Zone",
"41.804526", "-77.075572", "Something",
"41.804398", "-77.0743704", "Some Other Thing",
"41.8073731", "-77.07304", "Pedestrian"]
One big string array with everything in its own index. Next I'm using a loop and building a string in order to pass it to a datatables table. The result of which SHOULD look like this:
var dataString = [
["41.8059016", "-77.0727825", "School Zone"],
["41.804526", "-77.075572", "Something"],
["41.804398", "-77.0743704", "Some Other Thing"],
["41.8073731", "-77.07304", "Pedestrian"]
];
Instead I'm getting this:
var dataString = undefined["41.8059016", "-77.0727825", "School Zone"],
["41.804526", "-77.075572", "Something"],
["41.804398", "-77.0743704", "Some Other Thing"],
["41.8073731", "-77.07304", "Pedestrian"]
];
Here is my loop code to build the string from the array:
for(var i = 0; i < routePoints.length-3; i+=3){
console.log(routePoints);
if(i >= 0 && i < routePoints.length - 4){
dataSetString += '["' + routePoints[i] + '", "' + routePoints[i + 1] + '", "' + routePoints[i + 2] + '"],';
}else if(i == routePoints.length - 3){
dataSetString += '["' + routePoints[i] + '", "' + routePoints[i + 1] + '", "' + routePoints[i + 2] + '"]';
}
}
If I simply deleted the "undefined" and paste the code in, the datatabe populates fine, but I cannot see where the undefined is even coming from. Thanks for the second set of eyes!
Usually, the undefined comes from your initialization. I don't see the code here, but you probably have something like:
var dataSetString;
instead, you should always start an empty string as:
var dataSetString = "";
As to why this happens. All uninitialized variables default to undefined. When you use the += operation, it will try to interpret what your are doing (if you have two numbers it will add them, two strings: concatenate). Undefined has no good += operation, so it uses the second part of the operation the string you are passing in. So, it automatically converts the undefined to a string and concatenates the new string to it, ending up with "undefined[blah,blah,blah"
You shouldn't compose a String like that.
It doesn't look like you need a string anyway but a 2D array.
var data = ["41.8059016", "-77.0727825", "School Zone",
"41.804526", "-77.075572", "Something",
"41.804398", "-77.0743704", "Some Other Thing",
"41.8073731", "-77.07304", "Pedestrian"
];
var dataString = [];
for (var i = 0; i < data.length; i+=3) dataString.push(data.slice(i, i + 3));
console.log(dataString);
// Should you actually need a string, you can use JSON.stringify()
console.log(JSON.stringify(dataString));

Shorthand for "console.log("var: " + var)"?

It would be nice to have a super quick way to do this:
"console.log("var: " + var)"?
Tried this, but not sure if there's a way to get a variable name as a string once it's been passed in, or convert the name string to a reference to the variable...
var mLog = function(varNameStr){
console.log(varNameStr + ": " + _____);
}
EDIT: Judging by the results of googling "get name string of a variable js", it looks like there's no easy way to grab the name string of a variable from the reference (You have to create hash tables or other structures that make it not worthwhile.)
So, the only possible solution would be to convert a string into a reference to the variable. Is that possible in JS?
The following will do the trick. Pass it a variable name in string form.
var mLog = function(varStr){
console.log(varStr + ": " + eval(varStr));
}
Example:
> var strVar = 'A string variable';
> mLog('strVar');
< strVar: A string variable
> var arrVar = [1,2,3];
> mLog('arrVar');
< arrVar: 1,2,3
There is no way to "extract" the variable name, since variables aren't actually data. The closest thing you could do is use it for objects. Something like:
var obj= {
prop: 'value'
};
function mLog(object, prop) {
console.log(prop + ': ' + object[prop];
}
mLog(obj, 'prop');

JS var inside query does not work when stringed together

I have the following code which is really bloated
$(".field-name-field-parts-status .field-item:contains('Submitted'), .field-name-field-parts-status .field-item:contains('Saved'), .field-name-field-parts-status .field-item:contains('HMNZ Approved')").addClass('btn-primary');
I tried to neaten it up by adding a var
var fieldItemStatus = $(".field-name-field-parts-status .field-item");
So it looked like this
$(fieldItemStatus + ":contains('Submitted'), " + fieldItemStatus + ":contains('Saved'), " + fieldItemStatus + ":contains('HMNZ Approved')").addClass('btn-primary');
But it stopped working, can anyone tell me what I did wrong? Thanks
Because you are trying to add a jQuery object and a string together. It does not work like that.
var fieldItemStatus = $(".field-name-field-parts-status .field-item");
should be a string
var fieldItemStatus = ".field-name-field-parts-status .field-item";
other option is to use filter.
You need to use .filter()
fieldItemStatus.filter(":contains('Submitted'), :contains('Saved'), :contains('HMNZ Approved')").addClass('btn-primary');
fieldItemStatus is an object so
fieldItemStatus + ":contains('Submitted'), " + fieldItemStatus + ":contains('Saved'), " + fieldItemStatus + ":contains('HMNZ Approved') will create a string like [Object object]:contains('Submitted'), [Object object]:contains('Saved'), [Object object]:contains('HMNZ Approved')
remove $ in front for fieldItemStatus
var fieldItemStatus = ".field-name-field-parts-status .field-item";
Because you want to use a jQuery Object to concat string. The right way to do this is using string all the time.
var fieldItemStatus = ".field-name-field-parts-status .field-item";
$(fieldItemStatus + ":contains('Submitted'), " + fieldItemStatus + ":contains('Saved'), " + fieldItemStatus + ":contains('HMNZ Approved')").addClass('btn-primary');
You could use the filter method:
fieldItemStatus.filter(":contains('Submitted'), :contains('Saved'), :contains('HMNZ Approved')").addClass('btn-primary');
Another option is using the filter callback function:
var items = ['Submitted', 'Saved', 'HMNZ Approved'];
fieldItemStatus.filter(function(_, el) {
return items.some(function(item) {
return el.textContent.indexOf(item) > -1;
});
});
.
A more procedural approach. This way if you want to easily change the selectors, just change the contains array. You could turn this into a function to easily retrieve your selector on demand elsewhere in the script.
var contains = ['Submitted','Saved','HMNZ Approved'];
var selector = '';
for(var i = 0; i < contains.length; i++) {
selector += '.field-name-field-parts-status .field-item:contains("' + contains[i] + ')';
if(i < contains.length - 1) selector += ', ';
}
$(selector).addClass('btn-primary');

Replace array-mapped variables with the actual variable name/string?

I am trying to edit a Greasemonkey/jQuery script. I can't post the link here.
The code is obfuscated and compressed with minify.
It starts like this:
var _0x21e9 = ["\x67\x65\x74\x4D\x6F\x6E\x74\x68", "\x67\x65\x74\x55\x54\x43\x44\x61\x74\x65", ...
After "decoding" it, I got this:
var _0x21e9=["getMonth","getUTCDate","getFullYear", ...
It is a huge list (500+ ). Then, it has some variables like this:
month = date[_0x21e9[0]](), day = date[_0x21e9[1]](), ...
_0x21e9[0] is getMonth, _0x21e9[1] is getUTCDate, etc.
Is it possible to replace the square brackets with the actual variable name? How?
I have little knowledge in javascript/jQuery and can not "read" the code the way it is right now.
I just want to use some functions from this huge script and remove the others I do not need.
Update: I tried using jsbeautifier.org as suggested here and in the duplicated question but nothing changed, except the "indent".
It did not replace the array variables with the decoded names.
For example:
jsbeautifier still gives: month = date[_0x21e9[0]]().
But I need: month = date["getMonth"]().
None of the online deobfuscators seem to do this, How can I?
Is there a way for me to share the code with someone, at least part of it? I read I can not post pastebin, or similar here. I can not post it the full code here.
Here is another part of the code:
$(_0x21e9[8] + vid)[_0x21e9[18]]();
[8] is "." and [18] is "remove". Manually replacing it gives a strange result.
I haven't seen any online deobfuscator that does this yet, but the principle is simple.
Construct a text filter that parses the "key" array and then replaces each instance that that array is referenced, with the appropriate array value.
For example, suppose you have a file, evil.js that looks like this (AFTER you have run it though jsbeautifier.org with the Detect packers and obfuscators? and the Unescape printable chars... options set):
var _0xf17f = ["(", ")", 'div', "createElement", "id", "log", "console"];
var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);
var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);
var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];
window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);
In that case, the "key" variable would be _0xf17f and the "key" array would be ["(", ")", ...].
The filter process would look like this:
Extract the key name using text processing on the js file. Result: _0xf17f
Extract the string src of the key array. Result:
keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
In javascript, we can then use .replace() to parse the rest of the JS src. Like so:
var keyArrayStr = '["(", ")", \'div\', "createElement", "id", "log", "console"]';
var restOfSrc = "var _0x41dcx3 = eval(_0xf17f[0] + '{id: 3}' + _0xf17f[1]);\n"
+ "var _0x41dcx4 = document[_0xf17f[3]](_0xf17f[2]);\n"
+ "var _0x41dcx5 = _0x41dcx3[_0xf17f[4]];\n"
+ "window[_0xf17f[6]][_0xf17f[5]](_0x41dcx5);\n"
;
var keyArray = eval (keyArrayStr);
//-- Note that `_0xf17f` is the key name we already determined.
var keyRegExp = /_0xf17f\s*\[\s*(\d+)\s*\]/g;
var deObsTxt = restOfSrc.replace (keyRegExp, function (matchStr, p1Str) {
return '"' + keyArray[ parseInt(p1Str, 10) ] + '"';
} );
console.log (deObsTxt);
if you run that code, you get:
var _0x41dcx3 = eval("(" + '{id: 3}' + ")");
var _0x41dcx4 = document["createElement"]("div");
var _0x41dcx5 = _0x41dcx3["id"];
window["console"]["log"](_0x41dcx5);
-- which is a bit easier to read/understand.
I've also created an online page that takes JS source and does all 3 remapping steps in a slightly more automated and robust manner. You can see it at:
jsbin.com/hazevo
(Note that that tool expects the source to start with the "key" variable declaration, like your code samples do)
#Brock Adams solution is brilliant, but there is a small bug: it doesn't take into account simple quoted vars.
Example:
var _0xbd34 = ["hello ", '"my" world'];
(function($) {
alert(_0xbd34[0] + _0xbd34[1])
});
If you try to decipher this example, it will result on this:
alert("hello " + ""my" world")
To resolve this, just edit the replacedSrc.replace into #Brock code:
replacedSrc = replacedSrc.replace (nameRegex, function (matchStr, p1Str) {
var quote = keyArry[parseInt (p1Str, 10)].indexOf('"')==-1? '"' : "'";
return quote + keyArry[ parseInt (p1Str, 10) ] + quote;
} );
Here you have a patched version.
for (var i = 0; i < _0x21e9.length; i++) {
var funcName = _0x21e9[i];
_0x21e9[funcName] = funcName;
}
this will add all the function names as keys to the array. allowing you to do
date[_0x21e9["getMonth"]]()

jQuery - parsing JSON data - Having trouble with variable name

My first delve into working with JSON data. I have a bit of experience using jQuery though.
I'm posting to this URL (tumblr api): jyoseph.com/api/read/json
What I'm trying to do is output the json that gets returned. What I have so far:
$(document).ready(function(){
$.getJSON("http://jyoseph.com/api/read/json?callback=?",
function(data) {
//console.log(data);
console.log(data.posts);
$.each(data.posts, function(i,posts){
var id = this.id;
var type = this.type;
var date = this.date;
var url = this.url;
var photo500 = this.photo-url-500;
$('ul').append('<li> ' +id+ ' - ' +type+ ' - ' +date+ ' - ' +url+ ' - ' +photo500+ ' - ' + ' </li>');
});
});
});
See my jsbin post for the entire script: http://jsbin.com/utaju/edit
Some of the keys from tumblr have "-" hyphens in them, and that seem to be causing a problem. As you can see "photo-url-500" or another "photo-caption" is causing the script to break, it's outputting NaN.
Is there a problem with having hyphens in the key names? Or am I going about this all wrong?
If there are dashes in the names you'll need to access them differently. Change var photo500 = this.photo-url-500; to read var photo500 = this["photo-url-500"];.
Please note it is best not to append inside each iteration. Better to append to a string or push to an array then append once after the iterator has finished. Appending to the dom is expensive.
Use the bracket notation to access the members:
var photo500 = this['photo-url-500'];

Categories

Resources