how to change property name by argument in javascript - javascript

I have some function:
function funcName(first_data, SECOND_DATA) {
// ...some code here...
data: {dontMatterProp: dontMatterVal, SECOND_DATA: SECOND_DATA},
// ...some code.....
}
I need that my property name 'SECOND_DATA' changes too!
for example in php a could do something like {SECOND_DATA}...

Your question is a little unclear, but I think something like this is what you are looking for:
function funcName(first_data, SECOND_DATA_KEY, SECOND_DATA_VALUE) {
// ...some code here...
x = {}
x.data = {dontMatterProp: dontMatterVal}
x.data[SECOND_DATA_KEY] = SECOND_DATA_VALUE
// ...some code.....
}
If you just want the key to be equal to the value, you could just do
x.data[SECOND_DATA] = SECOND_DATA
But that's a little odd. Why map something to itself? No value necessary, you can just verify that the key exists if that's the case...
You can use brackets for dynamic keys in javascript. So,
var x = {}
x['something'] = 'test'
// x === { 'something': 'test' }
x[something] = 'test2'
// error: something is undefined
var something = 'hello'
x[something] = 'test3'
// x === { 'something': 'test', 'hello': 'test3' }
Hope that helps?

I think you want:
data[SECOND_DATA] = SECOND_DATA; // assign the value
If you just use:
var data = { SECOND_DATA: SECOND_DATA };
using object notation - the property name will ALWAYS be SECOND_DATA

Related

updating object does not show the new property

the code in the example works fine but in my codes it doesn't
I`m trying to update object with a new property
const overrides = {paths:{"/":{}}}
const aItems = [{endpoint:"/test"}]
const mockOverrides = JSON.parse(JSON.stringify(overrides));
aItems.forEach(({endpoint}) => {
if (!mockOverrides.paths[endpoint]) {
mockOverrides.paths[endpoint] = {};
}
console.log(mockOverrides); // result {paths:{"/":{}}} expected {paths:{"/":{}, "/test":{}}}
console.log(mockOverrides.paths[endpoint]) // result is {} twice
})
as you can see the property is not displayed in the output
but is somehow exist why this happening?
After adding a ) to the end of the foreach method, it appears to be working fine:
const overrides = {paths:{"/":{}}}
const aItems = [{endpoint:"/test"}]
const mockOverrides = JSON.parse(JSON.stringify(overrides));
aItems.forEach(({endpoint}) => {
if (!mockOverrides.paths[endpoint]) {
mockOverrides.paths[endpoint] = {};
}
console.log(mockOverrides); // result {paths:{"/":{}}} expected {paths:{"/":{}, "/test":{}}}
console.log(mockOverrides.paths[endpoint]) // result is {} twice
});
Yeah. I wrote that but it was deleted. You were missing the ). Other than that the code is fine.
Maybe because the new property was set to __proto__ of mockOverrides.paths
why console.log doesn't show values of properties added by PROTOTYPES in javascript when whole object is printed?
You can reproduce it by run below code on chrome console (also get from the quote above)
var Person=function (name) {
this.Fname=name;
this.health=100;
};
var Mateen=new Person("Mateen");
console.log(Mateen);
// result: { Fname: 'Mateen', health: 100 }
Person.prototype.level=1;
console.log(Mateen);
// result: { Fname: 'Mateen', health: 100 }
console.log(Mateen.level);
// result: 1

Compare value within nested object

So I've been trying to find a solution to this for a little while with no luck.
const nameTest = 'testName';
const test = {
RANDOM_ONE: {
NAME: 'testName',
SOMETHING: {...}
},
RANDOM_TWO: {
NAME: 'Name',
SOMETHING: {...}
}
}
Is there any simple, easy way where I can compare the nameTest and the NAME key without knowing what the RANDOM_X is in order to access NAME?
You can use Object.keys() to get the array of all the keys. Then loop through the array to check the property:
const nameTest = 'testName';
const test = {
RANDOM_ONE: {
NAME: 'testName',
SOMETHING: {}
},
RANDOM_TWO: {
NAME: 'Name',
SOMETHING: {}
}
}
let testKeys = Object.keys(test);
testKeys.forEach(function(k){
console.log(test[k].NAME == nameTest);
});
You can use a for ... in loop:
for (let key in test) {
if (test[key].NAME === nameTest) {
// do something
}
}
I hope we know that 2 levels down into test is your object. You could write a function, to compare the name key.
function compare(obj, text){
for(let x in obj){
if(obj.x.name == text) return true;
else ;
}
}
Then call the function with your object and the string.
let a = compare(test, nameTest);
Note: this would compare the object to only ascertain if it contains the nameTest string.
var obj= test.filter(el){
if(el.NAME==nameTest)
{
return el;
}
}
var x= obj!=null?true:false;
You could use find.
The find method executes the callback function once for each index of
the array until it finds one where callback returns a true value. If
such an element is found, find immediately returns the value of that
element. Otherwise, find returns undefined.
So it is more memory efficient, than looping over the whole object with forEach, because find returns immediately if the callback function finds the value. Breaking the loop of forEach is impossible. In the documentation:
There is no way to stop or break a forEach() loop other than by
throwing an exception. If you need such behavior, the forEach() method
is the wrong tool.
1. If you want to get the whole object
var nameTest = 'testName';
var test = {
RANDOM_ONE: {
NAME: 'testName',
SOMETHING: {}
},
RANDOM_TWO: {
NAME: 'Name',
SOMETHING: {}
}
};
function getObjectByNameProperty(object, property) {
var objectKey = Object.keys(object)
.find(key => object[key].NAME === property);
return object[objectKey];
}
var object = getObjectByNameProperty(test, nameTest);
console.log(object);
2. If you just want to test if the object has the given name value
var nameTest = 'testName';
var test = {
RANDOM_ONE: {
NAME: 'testName',
SOMETHING: {}
},
RANDOM_TWO: {
NAME: 'Name',
SOMETHING: {}
}
};
function doesObjectHaveGivenName(object, nameValue) {
var objectKey = Object.keys(object)
.find(key => object[key].NAME === nameValue);
return objectKey ? true : false;
}
console.log( doesObjectHaveGivenName(test, nameTest) );

Substitute variables in strings like console.log

I want to substitute variables in a string like console.log does.
What I want to achieve is something like this:
let str = 'My %s is %s.';
replaceStr(string, /* args */) {
// I need help with defining this function
};
let newStr = replaceStr(str, 'name', 'Jackie');
console.log(newStr);
// output => My name is Jackie.
/*
This is similar to how console.log does:
// console.log('I\'m %s.', 'Jack');
// => I'm Jack.
*/
I am not able to figure out how to do that. Any help will be much appreciated.
Thank you.
You could prototype it to the String object. Something like this:
String.prototype.sprintf = function() {
var counter = 0;
var args = arguments;
return this.replace(/%s/g, function() {
return args[counter++];
});
};
let str = 'My %s is %s.';
str = str.sprintf('name', 'Alex');
console.log(str); // 'My name is Alex'
You can use spread operator (ES6):
function replaceStr(string, ...placeholders) {
while (placeholders.length > 0) {
string = string.replace('%s', placeholders.shift());
}
return string;
}
EDIT: Based on lexith's answer, we can avoid the explicit loop:
function replaceStr(string, ...placeholders) {
var count = 0;
return string.replace(/%s/g, () => placeholders[count++]);
}
If hope you want to have custom logger function.
console.log can replace %s, with below approach your custom function gets full feature set of console.log and its more efficient.
function myLogger() {
if(logEnabled) {
// you can play with arguments for any customisation's
// arguments[0] is first string
// prepend date in log arguments[0] = (new Date().toString()) + arguments[0] ;
console.log.apply(console, arguments);
}
}
function replaceStr(string, ...placeholders) {
const replaced = string.replace(/%s/g, () => placeholders.shift());
return [replaced, ...placeholders].join(' ');
}
This will append any remaining placeholders to the string to more accurately replicate console.log.

How can I pass a JS object literal name value pair to another function

Given a JS literal object like:
var foo = {
_stuff : {
a:10,
b:20,
c:30,
state
}
}
and literal functions
addAB: function() {
add(foo._stuff[a], foo._stuff[b]);
}
addAC: function() {
add(foo._stuff[a], foo._stuff[c]);
}
add: function(bar, baz) {
foo._stuff[bar] += foo._stuff[baz];
state(foo._stuff[bar]);
}
state: function(value) {
foo.state[value] = .... something complex ....
}
How can I get the following in one pass ?
add(AB); foo._stuff[a] should be 30, foo.state[foo._stuff[a]] is something new
add(AC); foo._stuff[a] should be 40, foo.state[foo._stuff[a]] is something new
As is add() will try to lookup foo._stuff[10] which clearly wont do what I want.
Yes I know there is redundancy with addAB() and addAC() but that is out of my control.
Pass the index instead of the value, like this:
addAB: function() {
add('a', 'b');
}
addAC: function() {
add('a', 'c');
}
add: function(bar, baz) {
if (arguments.length === 1) {
this['add' + arguments[0]];
} else {
foo._stuff[bar] += foo._stuff[baz];
state(foo._stuff[bar]);
}
}
// assuming you are calling
var AB = 'AB', AC = 'AC';
add(AB);
add(AC);
Otherwise, I have not a clue what you are asking.
I'm not sure if I totally follow what you want to accomplish, but your object literal is not valid syntax. I don't see why you want the _stuff property. And, you need to initialize the state property to some value, even if it's undefined. But, since you want to store values in the state property based on some property name, you should initialize state to be an object.
var foo = {
a:10,
b:20,
c:30,
state: {}
}
Your javascript:
addAB: function() {
add('a', 'b');
}
addAC: function() {
add('a', 'c');
}
add: function(propName0, propName1) {
foo[propName0] += foo[propName1];
state(propName0);
}
state: function(propName) {
// state is initialized to an object, so can store properties in there now
foo.state[propName] = .... something complex ....
}

jQuery function not returning

(function($){
$.a.b = {
title: "ABC",
init: function (id) {
/* do something here */
return id+'a';
}
};
})(jQuery);
When I try to call $.a.b.init('t'); it does not work, I mean it does not return as expected. Any suggestions?
The problem is not that $.a.b.init('t') is not working. Problem is that it returns the code of the whole function instead of returning say a string.
Thank you for your time.
try
$.a = [];
$.a.b = { ... }
or even better:
$.a = {b: {
title: "",
init: ...
}};
When using $.a.b a is undefined, so you cannot add to it.
Since $.a is not yet defined you cannot set the b property. First you'll need to create $.a. Alternatively, use a namespacing helper:
$.namespace = function(ns) {
var cur = $, split = ns.split('.');
while (split[0]) {
cur = cur[split.shift()] = {};
}
return cur;
};
$.namespace('a').b = { ... };
It can also be used with deeper namespaces:
$.namespace('a.b.c.d.e.f').g = 123;
$.a.b.c.d.e.f.g; // => 123

Categories

Resources