different javascript object keys seem to be evaluated as being the same - javascript

I'm using an object as a map and storing objects in it using the pattern map[obj.href] = obj
I'm expecting duplicate keys, but something really weird is happening:
I have 2 completely different (every field) objects stored with different keys, but when a 3rd object has the same key as 1st, a lookup is returning the 2nd object (stored with a different key), and when I do a lookup of the returned object's href, I get that same object again, as if the 2 keys are equivalent.
According to Which characters are valid/invalid in a JSON key name? and some other posts on SO, any valid string can be a key in an object, and you don't need to escape any characters, which I was worried about because of all the '/'s and '#'s.
I'm sureit's just a simple bug in my code, which I can't see it because it's 8 am and I have been up all night. Any help spotting it would be appreciated.
function parseSpellsList($)
{
var spellsList = {};
$("ul[class|='link'],ul[class$='level']").each(function() {
var obj, spell_type, links, i, link, a, span, prevObj, hashKey;
obj = {};
links = this.children;
for (i=0; i<links.length; i++) {
link = links[i];
a = link.children[0];
obj.href = a.href.replace("file:///home/ckot/rpg_app/", "").replace("scripts/", "");
obj.name = a.innerHTML.replace("<b>", "").replace("</b>", "");
hashKey = obj.href;
prevObj = null;
if ( !(spellsList.hasOwnProperty(hashKey))) {
// debug code
if ("Blood Blaze" === obj.name || "Vomit Swarm" === obj.name) {
console.log("storing " + JSON.stringify(obj, null, " ") + " with hashKey: " + hashKey);
}
spellsList[hashKey] = obj;
} else {
console.log("\nWARNING: hashKey " + hashKey + " already exists");
prevObj = spellsList[hashKey];
console.log("object we which to store with hashKey: " + hashKey + "\n" + JSON.stringify(obj, null, " ")) ;
console.log("object retrieved with hashKey: " + hashKey + "\n" + JSON.stringify(prevObj, null, " "));
console.log("object retrieved with hashKey: " + prevObj.href + "\n" + JSON.stringify(spellsList[prevObj.href], null, " ") + "\n");
}
}
});
}
when I run it I get the following output:
storing {
"href": "advancedRaceGuide/featuredRaces/orcs.html#blood-blaze",
"name": "Blood Blaze"
} with hashKey: advancedRaceGuide/featuredRaces/orcs.html#blood-blaze
storing {
"href": "advanced/spells/vomitSwarm.html#vomit-swarm",
"name": "Vomit Swarm"
} with hashKey: advanced/spells/vomitSwarm.html#vomit-swarm
WARNING: hashKey advancedRaceGuide/featuredRaces/orcs.html#blood-blaze already exists
object we which to store with hashKey: advancedRaceGuide/featuredRaces/orcs.html#blood-blaze
{
"href": "advancedRaceGuide/featuredRaces/orcs.html#blood-blaze",
"name": "Blood Blaze"
}
object retrieved with hashKey: advancedRaceGuide/featuredRaces/orcs.html#blood-blaze
{
"href": "advanced/spells/vomitSwarm.html#vomit-swarm",
"name": "Vomit Swarm"
}
object retrieved with hashKey: advanced/spells/vomitSwarm.html#vomit-swarm
{
"href": "advanced/spells/vomitSwarm.html#vomit-swarm",
"name": "Vomit Swarm"
}
EDIT:
just for some context I'm using:
node v0.10.22
npm v1.4.24
and the npm modules:
jsdom v1.0.0-pre.3
jquery v2.1.1",

nvm, I was initializing obj at the start of $.each() instead of inside the nested for loop. :(
i guess I just need to get some sleep.

Related

Merge/concatenate select properties in javascript/typescript array

I have a function that pulls drugs into a javascript object from the server via odata and it currently returns an array of drugs in json.
How do I create a display name property on the return object that concatenates/joins certain properties so that the returned drug array has a new property called displayname that should equal to following string:
"Dosage:" + drug.Name + "-" + drug.AlternateNames + " (" + drug.Type + ") " + drug.Indication
Code to pull from the server is below:
getDsTeamSiteDrugs = function () {
var drugsUrl = environment.odataUrl + "Drug";
return this.http.get(drugsUrl + '?' + queryStr, options)
.map((drugs) => this.processDsTeamSiteDrugs(drugs))
}
processDsTeamSiteDrugs(response) {
return <any[]>response.json()
}
An example response array is
[{"deleted":false,"updatedAt":null,"createdAt":"2017-12-09T05:34:30.816Z","version":"AAAAAAAAJ6Q=","id":"48","type":"mg/ml","allConcentration":"15mg/ml","concentration":"15mg/ml","animalTypeId":"af280864-db83-11e7-9296-cec278b6b50a","notes":"q4-6h","perWeightMax":2.00,"perWeightMin":0.25,"perWeight":0.00,"perWeightTypeId":"c51d9efe-db83-11e7-9296-cec278b6b50a","route":"SQ,IM","indication":"Analgesia","alternateNames":"","name":"Morphine","drugCategory":"Analgesic"},{"deleted":false,"updatedAt":null,"createdAt":"2017-12-09T05:34:30.843Z","version":"AAAAAAAAJ7g=","id":"72","type":"mg/ml","allConcentration":"15mg/ml","concentration":"15mg/ml","animalTypeId":"af280e7c-db83-11e7-9296-cec278b6b50a","notes":"q4-6h","perWeightMax":0.30,"perWeightMin":0.10,"perWeight":0.00,"perWeightTypeId":"c51d9efe-db83-11e7-9296-cec278b6b50a","route":"SQ,IM","indication":"Analgesia","alternateNames":"","name":"Morphine","drugCategory":"Analgesic"},{"deleted":false,"updatedAt":null,"createdAt":"2017-12-09T05:34:30.846Z","version":"AAAAAAAAJ70=","id":"78","type":"mg/ml","allConcentration":"15mg/ml","concentration":"15mg/ml","animalTypeId":"af280e7c-db83-11e7-9296-cec278b6b50a","notes":"use with mIdazolam or diazepam","perWeightMax":0.00,"perWeightMin":0.00,"perWeight":0.50,"perWeightTypeId":"c51d9efe-db83-11e7-9296-cec278b6b50a","route":"SQ,IM","indication":"Premed","alternateNames":"","name":"Morphine","drugCategory":"Anesthesia"},{"deleted":false,"updatedAt":null,"createdAt":"2017-12-09T05:34:30.85Z","version":"AAAAAAAAJ74=","id":"79","type":"mg/ml","allConcentration":"15mg/ml","concentration":"15mg/ml","animalTypeId":"af280864-db83-11e7-9296-cec278b6b50a","notes":"given with 0.05mg/kg Ace IM","perWeightMax":0.00,"perWeightMin":0.00,"perWeight":0.50,"perWeightTypeId":"c51d9efe-db83-11e7-9296-cec278b6b50a","route":"SQ,IM","indication":"Premed","alternateNames":"","name":"Morphine","drugCategory":"Anesthesia"}]
Expected result
"Dosage:" + drug.Name + "-" + drug.AlternateNames + " (" + drug.Type + ") " + drug.Indication
Dosage: Morphine- (mg/ml) Anesthesia Premed
After you get a Promise for your array of objects using response.json(), you can use then to make modifications to the array of objects once the response is available.
processDsTeamSiteDrugs(response) {
return response.json().then((drugs) => {
for (const drug of drugs) {
drug.displayname = `Dosage: ${drug.Name}-${drug.AlternateNames}(${drug.Type}) ${drug.Indication}`;
}
return drugs;
});
}
Thanks for the pointer. I was able to solve this using the map operator combined with 4castles code.
processDsTeamSiteDrugs(response) {
return response.json().map((drugs) => {
drugs.displayName = `Dosage: ${drugs.name}-${drugs.alternateNames}(${drugs.type}) ${drugs.indication}`;
return <any[]>drugs;
});
}

parse values from javascript object

I see there is a problem to get a String name from JSON object's name.
I need to parse this kind on JSON response from server.
var response = {
hopaopGmailsjIpW: {
GmailsjIpW_totalEmails_count: 133,
GmailsjIpW_state: 1
},
hopaopGmail4y4yu: {
Gmail4y4yu_totalEmails_count: 156,
Gmail4y4yu_state: 1
}
}
It is not an Array, but the object with inner objects.
i need to parse an inner ojects name and add additional values to each object.
i want be able to do something like this:
for(var i =0; i < response.length; i++){
response[i].username = parseUsernameFromString(response[i]);
response[i].service = parseServiceFromString(response[i]);
response[i].id = parseIdString(response[i]);
}
(and also state for each task)
So the question is:
What is the best way to make it?
UPDATE
this is exactly what i have for now:
for(var key in response){
if(stringContains(response[key], "Gmail")) { response[key].service = "Gmail";}
console.log("task name: "+ response[key].service);
}
function stringContains(originalString, searchString){
if(originalString.indexOf(searchString) > -1){
return true
}
else return false;
}
For walking through Objects, you need to use for ... in loop.
The real problem is: There's a , missing in your code. See the fixed working snippet:
Snippet
var response_Parsed = {
hopaopGmailsjIpW: {
GmailsjIpW_totalEmails_count: 133,
GmailsjIpW_state: 1,
service: 'Gmail',
username: 'hopaop',
id: 'sjIpW'
},
hopaopGmail4y4yu: {
Gmail4y4yu_totalEmails_count: 156,
Gmail4y4yu_state: 1,
service: 'Gmail',
username: 'hopaop',
id: '4y4yu'
}
};
for (id in response_Parsed) {
console.log("----");
if (id.indexOf("Gmail") > -1) {
console.log("We have Gmail: " + id);
console.log("UniqueName: " + id.replace("hopaopGmail", ""));
console.log("Username: " + response_Parsed[id].username);
console.log("Email Count: " + response_Parsed[id][id.replace("hopaop", "") + "_totalEmails_count"]);
}
else
console.log("We don't have Gmail: " + id);
}
And also the right way to enumerate the through the keys of the objects, is by using Object.keys.
If the response is a String like you wrote, you should first parse the JSON-String into an Object (if you're using a library like jQuery, it's probably already a JSON, as this conversion is done by jQuery automatically):
var obj = JSON.parse(responseString);
Afterwards you may iterate through it like posted above:
for (var key in obj) {
console.log("key", key, "value", obj[key]);
}

How read of Object.keys() value JSON?

How read of Object.keys() value JSON ?
I trying read value key name, but give error:
Keys dynamic
{
"marka1": {
"name": "Mika",
},
"beti1": {
"name": "Yii",
}
}
var ojson = JSON.parse(objectJson);
var keys = Object.keys(ojson); //read good key
console.log("test - " + ojson.keys[0].name); //give error
Change it to console.log("test - " + ojson[ keys[0] ].name); because keys[0] is just a string.

How to iterate over json with no name

var categories= {
"art": 352,
"health-beauty": 358,
"home": 372,
"jewelry": 339,
"kids": 320
}
for(var i in categories)
{
console.log("name: " + i + "id: " + ?);
}
I'm trying to import name of categories and id to mongodb but having hard time how to get the ID of each value? Is this possible or I have to re arrange the JSON file by hand?
Your var i contains the property and object's properties can be accessed using an arraylike notation. so:
for(var i in categories) {
console.log("name: " + i + "id: " + categories[i]);
}
I recommend that you always put your curly braces on the right because not doing so would yield unexpected results:
function someFunction ()
{
return
{
prop: "Prop"
}
}
alert(someFunction().prop); // Error, it returned undefined because something called semi-colon insertion. Read about it.

Replace multiple values in file loop

I'm trying to build a quick and dirty static site generator for myself.
Let's say I have this test.html file:
{title}
{downloadpath}
This is my current.json where I get the values i want to replace:
{
"id": 123,
"album" : [{
"title": "Test EP",
"albumid": 1234,
"path": "test.zip"
}]
}
My replacement function looks like this:
// Iterate through JSON object and replace
function iterate(obj) {
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object")
iterate(obj[property]);
else
console.log("replace {" + property + "} with " + obj[property] )
htmldata.replace(/\{property\}/g, obj[property]);
}
}
}
iterate(json)
var result = htmldata
console.log(result)
// Write new HTML
fs.writeFile("test-" + json.id + ".html", result, 'utf8', function (err) {
if (err) {
return console.log(err);
}
});
and if I run it it works like this:
replace {id} with 123
replace {title} with Test EP
replace {albumid} with 1234
replace {path} with test.zip
{title}
{path}
and you can see the problem right there. I think it's always replacing the edited file with the input file so I don't see any changes. I can't figure it out and if someone could point me in the right direction I'd be grateful.
Thanks!
Not using braces around your if statements will lead to subtle bugs!
You want:
if (typeof obj[property] == "object") {
iterate(obj[property]);
} else {
console.log("replace {" + property + "} with " + obj[property] )
htmldata.replace(/\{property\}/g, obj[property]);
}
Otherwise the replace will run every time regardless of the condition on the if.
Second thing: your regex tries to match the literal string "{property}". Instead, try this:
htmldata.replace(new RegExp("{" + property + "}", "g"), obj[property]);
Third thing: you're not assigning the result of the replace back to htmldata. So you need to do this:
htmldata = htmldata.replace(new RegExp("{" + property + "}", "g"), obj[property]);

Categories