JavaScript: Get the value of a dinamicly generated object - javascript

I know I can access the value of a user defined variable by composing its name like
window["myvariable"+1234]
What I don't know is how to access the value of inner properties. I want something like the following code, but that works:
//Suppose there is an object with user-generated property names like myCars.Ford.Focus.mileage and I need a function that reports the value of a certain property only when the content is not an empty string. So we create a function like
function squealProperty(maker,model,UDProp){
if(window["myCars."+maker+"."+model+"."+UDProp+".length"] > 0){
alert("User defined property inspector ("+UDProp+")="+window["myCars."+maker+"."+model+"."+UDProp]);
};
};
In moments like this, I usually find answers to my prayers in "The Book"[1] but no luck this time. So I ask here.
[1] By "The Book" I mean "JavaScript: The Definitive Guide", 5th Edition. By David Flanagan

You can not access the propertys as a single string when you access them with []. So you have to break them down. Also you code will break if you try to check all at one time, so you have to check just one "inner" property at every check.
function squealProperty(maker,model,UDProp){
if(window["myCars"] && window["myCars"][maker] && window["myCars"][maker][model] && window["myCars"][maker][model][UDProp] && window["myCars"][maker][model][UDProp].length > 0){
alert("User defined property inspector ("+UDProp+")="+window["myCars"][maker][model][UDProp]);
};
};

Access it in parts:
function squealProperty(maker,model,UDProp){
var obj = window.myCars;
if (obj &&
(obj = obj[maker]) &&
(obj = obj[model]) &&
(obj = obj[UDProp]) ) {
/* do something with obj */
}
}
var myCars = {maker: {model: {UDProp:[0,1,2,3]}}};
squealProperty('maker','model','UDProp'); // 4

Related

How to access property in function by sending values from function call

i am sending values from function call
this.checkname("models", "name");
this.checkname("designers", "name");
i want to access my object.method by using a function call=>
checkname = (key, value) =>{
const models = this.state.model;
const designers = this.state.designers;
if(key.value === ""){
console.log("Unanamed");
}
}
i am not able to access (key.value) how to do that?
You can’t use a variable to access an objects property with the „.“ notation instead use: key[value].
This of course only works, if the value supplied as „key“ argument is an object (as was pointed out in the comments).
Edit: Ok now I seem to actually understand what you’re trying to do. If you want to use either this.state.models or this.state.designers depending on what string is supplied as key, you will have to supply some kind of condition (if-else) to decide which to use. Something along the lines of:
let person;
if (key === "models") {
person = this.state.models;
} else if (key === "designers") {
person = this.state.designers;
}
if (person[value] === "") {
...
}

looping through objects to return objects with 'distinct' property - Javascript

I have a list of objects as shown in the image.
These all have the property statusCode: 62467 but the journey property goes like: 0,1,2,3,3,4,4,4,4
I want to loop through these objects and return the FIRST of the duplicated (they are not the same object, just that both have the same journey number and the same status code) objects with the same journey number.
So I want to return the bold objects: 0,1,2,3,3,4,4,4,4
$.each(points, function (index, point) {
for (i = 0; i < journeyNumber.length; i++) {
if (point.k.journey === journeyNumber[i] && point.k.statusCode === '62467') {
console.log(point);
latlngs.push(point.j.aa.k);
latlngs.push(point.j.aa.B);
}
}
});
The screenshot is the log of console.log(point), so ideally I would like another loop inside which returns only the first object of the same journey number.
Hope this makes sense and thank you for your time.
Try this,
var temp = [];
$.each(points, function (index, point) {
if (temp.indexOf(point.k.journey) === -1) {
temp.push(point.k.journey);
console.log(point);
latlngs.push(point.j.aa.k);
latlngs.push(point.j.aa.B);
}
});
Create a fresh object with status codes and check against that.
var journeys = {};
for(object in points){
// extract the properties you want (or use them directly, this is not necessary)
var journey = points[object].journey;
var status = points[object].statusCode;
// use the typeof operator to see if the journey has already been set before
if(typeof journeys[journey] == "undefined"){
// then define it.
journeys[journey] = status;
}
}
(Please note I am not actually correctly referencing the journey and statusCode, you'd have to do something like objects[object][k].journey to access the right property, but thats not really the point)
You can even add anything you want into the journeys object, nesting another object with the extracted latitude and longitude, or even just nesting the entire object in the journey!
journeys[journey] = points[object];
Now you can get every journey by looping through them again, and the associated first statusCode:
for(journey in journeys){
console.log("First instance of journey " + journey + " had statusCode " + journeys[journey]);
}

Setting a Javascript if statement with 2 requirements to one line

var status = result.locations[index].status;
var operator = result.locations[index].operator;
var original = result.locations[index].original;
var produced = result.locations[index].produced;
var href = result.locations[index].more;
I have the above which each need to be an if statement to check if there is content and my output is the below code.
if (result.locations[index] && result.locations[index].status){
var status = result.locations[index].status;
} else {
var status = '';
}
I would need to reproduce this per line from the code at the top of the post. What would be the best method to simplify each down to keep the code neater and not produce 5 lines of if statement when 1 or 2 would do.
var status = (result.locations[index] && result.locations[index].status ? result.locations[index].status : '');
Not sure why you want to, but:
var status = (result.locations[index] && result.locations[index].status) ? result.locations[index].status : ""
Your problem is trying to access a property of a "deep" javascript object using its path.
This is a common question :
Javascript: Get deep value from object by passing path to it as string
Accessing nested JavaScript objects with string key
There is no built-in way to do this in javascript.
There are plenty of libraries to do that, for example, with selectn, this would become something like (I have not tested it, so I don't know if the index part will work, but you get the idea) :
var status = selectn("locations." + index + ".status", result) || ''
If the structure of your objects is always the one above (that is, the property is just at one level of depth), and you're not expecting 'falsy', you could simply write the 'test' function yourself :
function safeGet(instance, propertyName, defaultValue) {
// As pointed by AlexK, this will not work
// if instance[propertyName] can be anything Falsy ("", 0, etc...)
// If it's possible, get a library that will do
// the full series of insane checks for you ;)
if (instance && instance[propertyName)) {
return instance[propertyName];
} else {
return defaultValue;
}
}
var location = result.locations[index]; // Potentially undefined, but safeGet will deal with it
var status = safeGet(location, "status", "");
var operator = safeGet(location, "operator", "DEFAULT_OPERATOR");
...
var status = result.locations[index] && result.locations[index].status || '';
However, better maje sure before, if result.locations[index] exists... else do whatever is to be done in your code..

JavaScript: querySelector Null vs querySelector

What is the main difference between these two methods of referencing?
What are the benefits of using one or the other? Also what kind of usage-case would they each be best suited to?
var selection = document.querySelector('.selector') !== null;
var selection = document.querySelector('.selector');
Is the former solely for browser legacy support?
The first one gets the reference and checks if the element exists, and saves this status as a boolean value in the variable. If the element exists, the variable contains true otherwise false.
You would use the first one if you only want to know if the element exists, but don't need the reference to it.
Example:
var selection = document.querySelector('.selector') !== null;
if (selection) {
alert('The element exists in the page.');
} else {
alert('The element does not exists in the page.');
}
The second one gets the reference and stores in the variable, but doesn't check if the element exists. If the element exists, the variable contains the reference to the element, otherwise the variable contains null.
You would use the second one if you need the reference to the element. If it's possible that the element doesn't exist in the page, you should check if the variable contains null before you try to do something with the reference.
Example:
var selection = document.querySelector('.selector');
if (selection !== null) {
alert('I have a reference to a ' + selection.tagName + ' element.');
} else {
alert('The element does not exists in the page.');
}
you could also do:
[].filter.call([document.querySelector('.single-selected-class')], item => item)
.forEach(item => item.blur());
The first statement contains a bool value depends on document.querySelector('.selector') is null or not
var selection = document.querySelector('.selector') !== null;
the second statement contains the actual value of document.querySelector('.selector');
var selection = document.querySelector('.selector');
You can try to avoid the conditional statement with:
var selection = document.querySelectorAll('.selector');
selection.forEach(function(item) {
alert(item);
});
Caution! querySelectorAll() behaves differently than most common JavaScript DOM libraries, which might lead to unexpected results
Source: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
I was developing a similar solution for CMS EFFCORE and came up with the following:
if (!Node.prototype.hasOwnProperty('querySelector__withHandler')) {
Object.defineProperty(Node.prototype, 'querySelector__withHandler', {
configurable: true,
enumerable : true,
writable : true,
value: function (query, handler) {
var result = this.querySelector(query);
if (result instanceof Node) {
handler(result);
}
}
});
}
document.querySelector__withHandler('a', function(link){
alert(link)
})

Can I loop through 2 objects at the same time in JavaScript?

related (sort of) to this question. I have written a script that will loop through an object to search for a certain string in the referring URL. The object is as follows:
var searchProviders = {
"google": "google.com",
"bing": "bing.com",
"msn": "search.msn",
"yahoo": "yahoo.co",
"mywebsearch": "mywebsearch.com",
"aol": "search.aol.co",
"baidu": "baidu.co",
"yandex": "yandex.com"
};
The for..in loop I have used to loop through this is:
for (var mc_u20 in mc_searchProviders && mc_socialNetworks) {
if(!mc_searchProviders.hasOwnProperty(mc_u20)) {continue;}
var mc_URL = mc_searchProviders[mc_u20];
if (mc_refURL.search(mc_URL) != -1) {
mc_trackerReport(mc_u20);
return false;
}
Now I have another object let's call it socialNetworks which has the following construct:
var socialNetworks = {"facebook" : "facebook.co" }
My question is, can I loop through both of these objects using just one function? the reason I ask is the variable mc_u20 you can see is passed back to the mc_trackerReport function and what I need is for the mc_u20 to either pass back a value from the searchProviders object or from the socialNetworks object. Is there a way that I can do this?
EDIT: Apologies as this wasn't explained properly. What I am trying to do is, search the referring URL for a string contained within either of the 2 objects. So for example I'm doing something like:
var mc_refURL = document.referrer +'';
And then searching mc_refURL for one of the keys in the object, e.g. "google.com", "bing.com" etc. 9this currently works (for just one object). The resulting key is then passed to another function. What I need to do is search through the second object too and return that value. Am I just overcomplicating things?
If I understand your question correctly, you have a variable mc_refURL which contains some URL. You want to search through both searchProviders and socialNetworks to see if that URL exists as a value in either object, and if it does you want to call the mc_trackerReport() function with the property name that goes with that URL.
E.g., for mc_refURL === "yahoo.co" you want to call mc_trackerReport("yahoo"), and for mc_ref_URL === "facebook.co" you want to call mc_trackerReport("facebook").
You don't say what to do if the same URL appears in both objects, so I'll assume you want to use whichever is found first.
I wouldn't create a single merged object with all the properties, because that would lose information if the same property name appeared in both original objects with a different URL in each object such as in an example like a searchProvider item "google" : "google.co" and a socialNetworks item "google" : "plus.google.com".
Instead I'd suggest making an array that contains both objects. Loop through that array and at each iteration run your original loop. Something like this:
var urlLists = [
mc_searchProviders,
mc_socialNetworks
],
i,
mc_u20;
for (i = 0; i < urlLists.length; i++) {
for (mc_u20 in urlLists[i]) {
if(!urlLists[i].hasOwnProperty(mc_u20))
continue;
if (mc_refURL.search(urlLists[i][mc_u20]) != -1) {
mc_trackerReport(mc_u20);
return false;
}
}
}
The array of objects approach is efficient, with no copying properties around or anything, and also if you later add another list of URLs, say programmingForums or something you simply add that to the end of the array.
You could combine the two objects into one before your loop. There's several approaches here:
How can I merge properties of two JavaScript objects dynamically?
var everything = searchProviders;
for (var attrname in socialNetworks) { everything[attrname] = socialNetworks[attrname]; }
for(var mc_u20 in everything) {
// ...
}
for (var i = 0; i < mc_searchProviders.length; i++) {
var searchProvider = mc_searchProviders[i];
var socialNetwork = mc_socialNetworks[i];
if (socialNetwork != undefined) {
// Code.
}
}
Or am i horribly misunderstanding something?

Categories