Parsing JSON string from python to Javascript - javascript

I am working on a terrarium controller project, at this moment I want to get the timeperiod of the lighting. In python I have a function called: getStatus() it returns a JSON string to Javascript, which will handle the data further. But it doesn't work.
Here's my python code:
def getStatus ():
data=[["HOUR_ON", HOUR_ON],["MINUTE_ON", MINUTE_ON], ["HOUR_OFF", HOUR_OFF], ["MINUTE_OFF", MINUTE_OFF]]
return json.dumps(data)
And overhere the Javascript:
var alertFunction = function macroCallback(macro, args, light) {
alert(macro + " returned with " + light);
var obj = JSON.parse(light);
document.getElementById("testSection").innerHTML="Light turns on at: "+ obj[0].HOUR_ON+":"+obj[0].MINUTE_ON + "\n"+"Light goes out at: "+obj[1].HOUR_OFF+":"+obj[1].MINUTE_OFF;
alert("after parsing: "+obj[0]);
document.getElementById("testSection").innerHTML=light;
}
The string seems to be send back from the server and will be parsed correctly, only accessing the string doesn't work I get four times undefined in the innerHTML section.
I hope someone can help me out!
Greetings and thanks!
Marco

Without changing your Python code, alter your javascript code to access the elements of the array using indices, not with attributes:
var alertFunction = function macroCallback(macro, args, light) {
alert(macro + " returned with " + light);
var obj = JSON.parse(light);
document.getElementById("testSection").innerHTML="Light turns on at: "+ obj[0][1]+":"+obj[1][1] + "\n"+"Light goes out at: "+obj[2][1]+":"+obj[3][1];
alert("after parsing: "+obj[0]);
document.getElementById("testSection").innerHTML=light;
}
However, it would be better to follow jcubic's advice and change your Python code to use a dictionary:
def getStatus ():
data={"HOUR_ON": HOUR_ON,
"MINUTE_ON": MINUTE_ON,
"HOUR_OFF": HOUR_OFF,
"MINUTE_OFF": MINUTE_OFF}
return json.dumps(data)
For example this produces a JSON string like this:
'{"HOUR_OFF": 13, "MINUTE_ON": 30, "MINUTE_OFF": 20, "HOUR_ON": 12}'
Also change your javascript to access the attributes of the object, which is much more readable:
var alertFunction = function macroCallback(macro, args, light) {
alert(macro + " returned with " + light);
var obj = JSON.parse(light);
document.getElementById("testSection").innerHTML="Light turns on at: "+ obj.HOUR_ON + ":" + obj.MINUTE_ON + "\n" + "Light goes out at: "+obj.HOUR_OFF+":"+obj.MINUTE_OFF;
alert("after parsing: "+obj[0]);
document.getElementById("testSection").innerHTML=light;
}

You've saved array instead of object try:
data=[{"HOUR_ON": HOUR_ON},{"MINUTE_ON": MINUTE_ON}, {"HOUR_OFF": HOUR_OFF}, {"MINUTE_OFF": MINUTE_OFF}]
or better just one object:
data={"HOUR_ON": HOUR_ON, "MINUTE_ON": MINUTE_ON, "HOUR_OFF": HOUR_OFF, "MINUTE_OFF": MINUTE_OFF}

Related

Compare values of object JavaScript

I have an object in JS like this:
var getToDoValue = document.getElementById("toDoInput").value;
var nameOfTeamMember = "Tobias";
var person = new Object();
person.task = "Task: " + getToDoValue;
person.member = "Member: " + nameOfTeamMember;
But problem comes when I try to enter the value of "nameOfTeamMember into an if statement:
var mem = person.member;
if (mem == "Tobias") {
console.log("works");
}
This does not work. But when I just console.log "var mem" outside of if statement it gives me "Member: Tobias". Any suggestions? Im still kinda new to JS so prob something with the comparisons
the issue with you code is that the value in person.member is "Member: Tobias" as you pointed out from the result of your console.log, which is the result from the line of code below where you are concatenating the name with the string "Memeber: " and assigning it to the member property.
person.member = "Member: " + nameOfTeamMember;
One option you could use to do the comparison would be:
if (mem.contains("Tobias", 8) {
console.log("works");
}
The 8 is so your search starts after the colon (:) so you don't include "Member:" in it, just what comes after it, which is the actual member name.

Returning a concatenated string from a functions' properties in javascript

I'm a total JS beginner. Here is the JsBin link formLetter test should be passing.
TL;DR
This:
var formLetter = function(recipient, msg, sender) {
return "Hello " + recipient + ",\n" + "\n" + msg + "\n" + "\nSincerely," + "\n" + sender
};
console.log(formLetter("Hermione", "Luna","How are you?"));
Should return:
"Hello Hermione,
How are you?
Sincerely,
Luna"
But instead I get this:
"Hello [object Object],
undefined
Sincerely,
undefined"
Edit
Sorry for the confusion. I'm working on different problems inside one JsBin. This is the correct JsBin with the isolated code.
This is because you are only getting one object passed into the function call. This object contains the information you need in lieu of the named arugments you have provided.
The first argument, recipient being [object Object] tells you that it's an object. undefined means that nothing was passed in their place. This signifies the common pattern of a config or param object being passed to the function call. Because of this, what you have as named arguments should really be property look ups on the object provided as the first argument.
Your function definition should look more like:
var formLetter = function (letter) {
// do something with letter
};
Inside of that function call, you may then hit the properties of the letter object to see if they contain what you need, Doing console.log debugging in dev tools will help track it down.
The line:
var formLetter = function(recipient, msg, sender) {
return "Hello " + recipient + ",\n" + "\n" + msg + "\n" + "\nSincerely," + "\n" + sender
};
in your example needs one semicolon after "sender", like:
var formLetter = function(recipient, msg, sender) {
return "Hello " + recipient + ",\n" + "\n" + msg + "\n" + "\nSincerely," + "\n" + sender;
};
Your undefined is related to the use of anidated console.log.
You do:
console.log(longMessage.formLetter("Hermione", "Luna","How are you?"));
and (in the JsBin) you have also:
var longMessage = {
formLetter: function(recipient, sender, msg) {
console.log("Hello " + recipient + ",\n" + "\n" + msg + "\n" + "\nSincerely," + "\n" + sender);
}
};
In the example of your question you have them corrected.
Double check the code you post, please.
After looking at your test in jsbin, I noticed that in your assert.deepEqual() method you run formLetter(letter) and compares it to the concatenated string you created.
The problem is that formLetter() expects three string values and you send it an object (letter). That's why you get [Object object] in the first location and undefined in the others.
You should run formLetter(letter.recipient, letter.msg, letter.sender) in your assert and it should work properly.

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');

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"]]()

Getting NaN Error and undefined Error

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/

Categories

Resources