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

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] === "") {
...
}

Related

JavaScript - IF statement inside FOR loop is outputting both options

I'm writing a function that searches an array from a prompt using an IF statement. So for I get the output I want if it is successful, but it also outputs the failure.
// The array I'm searching through
var statesArray = new Array();
statesArray['WI'] = "Wisconsin";
statesArray['MN'] = "Minnesota";
statesArray['IL'] = "Illinois";
// Now I'm trying to let the user search for the full state name from the two-letter abbreviation.
var stateSearch = prompt("enter a two letter state abbreviation")
for(var key in statesArray){
var value = statesArray[key]
if(stateSearch == key){
alert(value);
}else{
alert("try again");
}
}
So if I type "WI" in the prompt, I get "Wisconsin" and "try again".
Loop is not appropriate for this. Loop will check all values of array and check found or not for all.
var statesArray = new Array();
statesArray['WI'] = "Wisconsin";
statesArray['MN'] = "Minnesota";
statesArray['IL'] = "Illinois";
// Now I'm trying to let the user search for the full state name from the two-letter abbreviation.
var stateSearch = prompt("enter a two letter state abbreviation");
let searchObj =statesArray[stateSearch];
if(searchObj == null){
alert("try again");
}else{
alert(searchObj);
}
Your for loop isn't exiting after it has found a match. Either put it in a function and return when you find a match or break the for loop
for(var key in statesArray){
var value = statesArray[key]
if(stateSearch == key){
alert(value);
break;
}else{
alert("try again");
}
}
function searchArray(arr){
for(var key in arr){
var value = arr[key]
if(stateSearch == key){
return value;
}
}
}
Note: Array was created to store a numbered list of elements. If you need to get values by keywords, it's better idea to use a common object instead:
var statesArray = {
WI: "Wisconsin",
MN: "Minnesota",
IL: "Illinois",
null: "Cancelled!"
};
var abbr = prompt("enter a two letter state abbreviation");
alert( statesArray[abbr] || "try again" );
// will return the value, if `abbr` key exists,
// and "try again" if statesArray[abbr] returned `undefined`
Instead of using a for loop, you could use:
var index = statesArray.indexOf(stateSearch);
which will set index to -1 if the value is not found, otherwise it will be set to the position in the array that the value was found.
Like some of the other comments and answers said, you're not breaking/exiting your loop early when a match is found, which is why you are continuing to iterate through even after you find the right value. Had you searched for MI, for example, you would see:
try again
Minnesota
try again
Firstly, it's generally considered a better practice, from a performance and ease of reading standpoint, to create Array literals than to use the JavaScript new keyword to create an Array instance.
Secondly, JavaScript does not technically allow for Associative Arrays (Hashes/HashMaps) (in other words, arrays with named indices). From the MDN Developer Documentation for Arrays:
Arrays cannot use strings as element indexes (as in an associative array) but must use integers. Setting or accessing via non-integers using bracket notation (or dot notation) will not set or retrieve an element from the array list itself, but will set or access a variable associated with that array's object property collection.
In your case, I would think a simple object or Map would suit you better. For Map:
// Define the Map.
const statesHashMap = new Map([
['WI', 'Wisconsin'],
['MN', 'Minnesota'],
['IL', 'Illinois']
]);
// You could also do:
statesHashMap.set('TX', 'Texas');
// Attain user input:
const stateSearchKey = prompt("Enter a two letter state abbreviation");
Then, to iterate over and find the right state, you'd have a few different options:
// Iterate with forEach.
statesHashMap.forEach((value, key) => {
if (stateSearchKey === key) {
console.log(value)
}
});
// Iterate with for..of
for (const key of statesHashMap.keys()) {
if (stateSearchKey === key) {
const state = statesHashMap.get(key);
console.log(state);
}
}
The problem with the forEach method above is that you can't break out without throwing an exception, which makes the for..of loop likely more favorable for you. If you want to show a message to the user when they don't get a state, you could use break statements:
// Iterate with for..of
for (const key of statesHashMap.keys()) {
if (stateSearchKey === key) {
const state = statesHashMap.get(key);
console.log(state);
break;
} else {
console.log('Try again');
break;
}
}
Or, to make it look nicer and as a better programming practice, encapsulate the operation in a function and return early when needed:
// Iterate with for..of
const findStateByAbbreviation = abbrev => {
for (const key of statesHashMap.keys()) {
if (stateSearchKey === key) {
const state = statesHashMap.get(key);
return console.log(state);
} else {
return console.log('Try again');
}
}
}
findStateByAbbreviation(stateSearchKey);
You should probably also use .toUpperCase() on the input from the user to ensure you match the key WI (for example) if the user provides wi.
Be wary of browser compatibility with the Map option, however.
Hope this helps.

problems with list scope javascript

I trying to make a function that tries to access the first item in a list to make a konami code website. The list is defined and then the function is defined to edit the list. This is code
<html><body>
<script>
var keys = [38,38,40,40,37,39,37,39,66,65];
function keyhandler (e) {
e = e || event;
console.log(e.keyCode);
var key = keys[0];
if (key == e.keyCode) {
console.log("correct key");
if (keys.length == 1){
console.log("konami");
} else {
var keys = keys[1,keys.length];
}
}
else {
var keys = [38,38,40,40,37,39,37,39,66,65];
}
}
document.onkeydown = keyhandler;
</script>
</body></html>
when I trigger the function by a key-press I get this error :
Uncaught TypeError: Cannot read property '0' of undefined the error is caused by the var key = keys[0] line
You're initializing another variable named keys inside of your function (var keys = keys[1, keys.length]). This shadows the outer variable. Remove the var keyword to access the correct variable.
Also, I believe you want to remove the first element from the list. To do so, use shift.
keys.shift();
This will modify the array directly so you don't need to assign the result to anything.
var keys = keys[1,keys.length];
You've created a new (locally scoped) keys variable inside your function and it is masking the one containing the array you are trying to read. Remember: var statements are hoisted.
Use different names for those two variables (or if they are supposed to be the same variable, remove the var statement from the inner one).
NB: In JavaScript, [1,keys.length] is just a comma operator it isn't a slice.
As Quentin said, hoisting is happening in your function.
Other posters here also said it, you are defining a new local variable in your function.
Let me just show your function with hoisting happening when Javascript interprets your code:
var keys = [38,38,40,40,37,39,37,39,66,65];
function keyhandler (e) {
// Javascript defines all the local variables at top.
// This is what hoisting is
var key;
var keys;
e = e || event;
console.log(e.keyCode);
// at this point, local variable keys isn't initialized,
// that's why you are getting the undefined error.
key = keys[0];
if (key == e.keyCode) {
console.log("correct key");
if (keys.length == 1){
console.log("konami");
} else {
// you are referencing a local variable here
keys = keys[1,keys.length];
}
}
else {
// you are referencing a local variable here
keys = [38,38,40,40,37,39,37,39,66,65];
}
}
document.onkeydown = keyhandler;
As other posters mention, simply removing the var from keys may fix your issue, if that's what intended, but I think it's important to understand what Javascript technically does in this situation.
the issue was that
var key = keys[0];
is not a javascript expression as mentioned in the comment it needed to be replaced with
var key = keys.slice(0,2);

Setting value of an objects property using dot notation?

I understand my title might be a little vague, but bear with me.
I was playing with localStorage, so I made some really simple thing I could just mess with in the console of Firefox.
I had the following code:
function saved(data) {
if (localStorage.getItem(data) !== null) {
return localStorage.getItem(data);
} else {
return false;
}
}
var Player = {
canOpenDoors: false ? saved('canOpenDoors') == false : saved('canOpenDoors'),
}
Player.setAbility = function(ability, value) {
Player.ability = value;
localStorage.setItem(ability, value);
}
Player.getAbility = function(ability) {
return Player[ability];
}
console.log(Player.canOpenDoors);
The part in question here is Player.ability = value inside the Player.setAbility function. Obviously, I'm expecting it to treat the ability part as the parameter passed into the function, so that if I do Player.setAbility('canOpenDoors', true) it sets Player.canOpenDoors to true. What I suspect is actually happening is it's setting Player.ability to true instead, as if I want ability to actually be a key of the object.
I can make it work by doing:
Player.setAbility = function(ability, value) {
Player[ability] = value;
localStorage.setItem(ability, value);
}
But unless I've been misinformed, it's not 'correct' to set values of an object as if it was like an associative array. Is there a way I can do this via dot notation, or perhaps I'm missing the point and there's a way to do this specifically for objects?

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]);
}

JavaScript: Get the value of a dinamicly generated object

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

Categories