This question might be ridiculous but I tried searching everywhere but I just can't find a good reference.
Why does some object in javascript has the structure like in the image attached below?
There is t character. And how do I convert the normal object to that form? For instance:
{
key: "training",
amount: 4500,
currency: "PLN",
label: "Training",
}
The character t is the class name of the object that is passed as the value of the key value. As user #Vishnudev mentioned in the comments.
Consider the following code to recreate the JavaScript object and its structure in the image.
Code
class t{
constructor( amount, currency, _sdkType) {
this.amount = amount
this.currency = currency
this._sdkType = _sdkType
}
}
let value = new t(4500, "PLN", "Money")
let object = {
value: value
}
console.log(object)
Output
Result as seen in the browser console.
Related
I have an array of countries, where each country have three properties.
const countries = [
{ name: "Poland", alpha: "POL", code: "616" },
{ name: "Hungary", alpha: "HUN", code: "348" },
// and so on...
]
Later on I want to easily access each country by any of these properties.
I was thinking of reducing this array to an object that would have three keys for each country pointing to the very same country object.
Something like this:
const countriesObject = countries.reduce((object, country) => {
const { name, alpha, code } = country;
// Create individual country object
object[name] = { ...country };
// Reference just created country object
object[code] = object[name];
object[alpha] = object[name];
return object;
});
In the end I could access each country object either by its name, code or alpha.
countriesObject["Poland"] // →
countriesObject["POL"] // → The same object
countriesObject["616"] // →
My question is, would it be considered good practice, or there are some better ways to achieve the same or similar result?
Thank you!
That's fine, as all of those keys, as you correctly noted, will be pointing to the same object. The biggest problem that I see here is that it's easy to reduce readability of the code by using this approach. Let's say we have this fragment:
console.log( countriesObject[id] );
The question is, what is id here? Is it full country name? or just alpha? or code? You might just not care, true, but if you do, consider giving them additional structure:
const countriesObject = countries.reduce((object, country) => {
const { name, alpha, code } = country;
const countryCopy = { ...country };
// it makes sense to place them on the same line to show the intent
object.name[name] = object.code[code] = object.alpha[alpha] = countryCopy;
return object;
}, { name: {}, code: {}, alpha: {} });
Another potential issue is that you won't be able to drop the countries easily from this object; it's not enough to delete just a single key pointing to it, you'll have to go and remove all three. But that doesn't seem to be a big thing here; this looks more like a dictionary.
You can indeed write it like this:
var countries = {[
"poland": {
alpha: "POL", code: "616"
},
"hungary": {
alpha: "HUN", code: "348"
}
]}
Accessing each country like this:
var poland = countries.poland;
This, in turn, produces more readable code:
var alpha = countries.poland.alpha;
instead of
var alpha = countries[0].alpha;
But there is no set preference.
Docs
That title might not make a lot of sense but please bear with me and I'll try to explain what I'm after.
I'm creating an Angular filter component that I can plug and play into various portions of my app. However, the question itself is more of a JavaScript question than an Angular one.
What I want to achieve is quite simple in theory but seems to be hard in practice (at least for me).
I want to give the user the ability to input an array of objects, and an array of object property names. I then want to filter the array of objects by either property 1 OR property 2.
Lets say we have the following setup:
inputtedObjects = [
{name: 'Bruce', gamerTag: 'BruceyBoi', email: 'b.banner#email.com'},
{name: 'Frank', gamerTag: 'BruceIsMyNemesis', email: 'f.francis#yahoo.com'},
{name: 'Steve', gamerTag: 'ScubaSteve', email: 'superstevo#live.com'}
];
filterProperties = ['name', 'gamerTag']
What I then want to do is essentially this operation:
let filteredObjects = inputtedObjects.filter(object =>
object[filterProperties[0]].toLowerCase().includes(searchTerm) ||
object[filterProperties[1]].toLowerCase().includes(searchTerm)
Where the searchTerm is a user inputted field from an input tag in HTML.
This would result in if the user was typing in "bruce" in the input, he would get the top two filtered results returned to him.
I have tried the following code:
let currentObjects = this.objects;
this.filterProperties.forEach(field => {
this.filteredObjects = currentObjects.filter(
object =>
object[field]
.toLowerCase()
.includes(searchTerm.toLowerCase())
);
});
However, the issue with the code above is that it filters as an AND and not an OR in the sense that it would work but if the user wrote "bruce" it would only return the first object as both of the properties must include "bruce" for the above code to work.
Now I can do this with some kind of switch case, as in if the filterProperties array is length 1 then we do:
let filteredObjects = inputtedObjects.filter(object =>
object[filterProperties[0]].toLowerCase().includes(searchTerm)
and if it's of length 2 we do:
let filteredObjects = inputtedObjects.filter(object =>
object[filterProperties[0]].toLowerCase().includes(searchTerm) ||
object[filterProperties[1]].toLowerCase().includes(searchTerm)
Etc.
Now obviously this is not very clean code, nor does it seem very efficient whatsoever. It's also not easy to scale and it would require some kind of error message if the user attempted to input too many "filterProperties" as it would depend on the amount of hardcoded switch case statements (bad code smell already).
What I would want to achieve then is for the user to be able to provide an array of infinite objects of a certain type with potentially hundreds of properties per object. Then the user says, I want to filter on these 6 property names, and then begins to type "test", it would then evaluate objects that match test on any one of these 6 properties provided. Not only objects that match test on all of these properties.
Any ideas on how I could potentially achieve this outcome?
You can use Array.some on the filterProperties array to see if one (or more) of the object properties contains the searchTerm:
inputtedObjects = [{
name: 'Bruce',
gamerTag: 'BruceyBoi',
email: 'b.banner#email.com'
},
{
name: 'Frank',
gamerTag: 'BruceIsMyNemesis',
email: 'f.francis#yahoo.com'
},
{
name: 'Steve',
gamerTag: 'ScubaSteve',
email: 'superstevo#live.com'
}
];
filterProperties = ['name', 'gamerTag'];
searchTerm = 'bruce';
filteredObjects = inputtedObjects.filter(object =>
filterProperties.some(p => object[p].toLowerCase().includes(searchTerm))
);
console.log(filteredObjects);
Try this, adds into a list when a match is found on any field instead of overwriting it.
let filtered = [];
inputtedObjects.forEach(obj => {
console.log(obj.name)
for (let field of filterProperties) {
if (obj[field].toLowerCase().includes(searchTerm.toLowerCase())) {
console.log(obj.name, field)
filtered.push(obj);
break;
}
}
});
https://jsfiddle.net/k1bj8zof/
I am attempting to set the value of a JSON object property, however when I run Object.property = value the entire JSON object is replaced with the string 229,.
In the following code block:
for(var i=0; i<config["profiles"].length; i++){
profile = config["profiles"][i];
out = {
"name":profile["name"],
"version":profile["version"].replace(/_/g, "."),
"mods":null,
"saves":null
}
console.log(out)
out.mods = getMods(profile);
console.log(out)
console.log(getSaves(profile))
out.saves = getSaves(profile);
console.log(out)
profiles.push(out);
}
return profiles;
The first 2 console.log(out) calls return a proper JSON object as expected.
The console.log(getSaves(profile)) prints the following:
[ { name: 'Hard Career ',
mode: 'CAREER',
funds: '275,520',
science: '229',
reputation: '721',
flights: '20' },
{ name: 'Sandbox ',
mode: 'SANDBOX',
funds: 0,
science: 0,
reputation: 0,
flights: '12' } ]
However, the print directly after out.saves = getSaves(profile) prints the following: 229,.
To make things even more complicated, this only occurs on one item in the config["profiles"] array.
If anyone has possible solutions to the problem, I would love to hear them. If you need more information about the code, I'll see what I can do.
Thanks in advance!
You should declare your variables with something like let profile =
If you don't do this profile and out will be global variables, which means each time through your for loop you are reassigning a single shared global variable. If you have other code that is also doing this it can very difficult to keep track of. Changing your code to:
let profile = config["profiles"][i];
let out = {
"name":profile["name"],
"version":profile["version"].replace(/_/g, "."),
"mods":null,
"saves":null
}
should help.
In C#, I can create a class that acts as a user-defined type, such as:
Public Class FullName
{
string FirstName;
string LastName;
}
Public Class Address
{
string Line1;
string Line2;
string City;
string State;
string Zip;
}
and then I can create:
Public Class Person
{
FullName Name;
Address HomeAddress;
Address WorkAddress;
}
This allows me to reference the data like:
Person Bob;
Bob.WorkAddress.Line1 = "123 Sycamore Rd";
Bob.HomeAddress.Line1 = "1313 MockingBird Ln";
Bob.FullName.LastName = "Smith";
etc...
Ultimately, I want to create a 2D array of Person, so I don't want to hardcode (pre-populate?) the data until I know what it is.
I'd like to be able to do the same thing in JavaScript (specifically node.js), but can't seem to find an obvious way of doing so. Is this just fundamentally the wrong approach, or am I just missing something?
In Javascript you can create data objects directly (no classes):
var bob = {
workAddress: { line1: "123 Sycamore" },
fullName: { lastName: "Smith" }
};
It's also possible to create a class, but it's usually not necessary for mere data objects.
Ultimately, I want to create a 2D array of Person, so I don't want to hardcode (pre-populate?) the data until I know what it is.
You can create an array and later add persons to it:
var persons = [];
...
persons.push(bob);
For a 2D array, create an array to contain your person arrays:
var persons2D = [];
...
persons2D.push(persons);
A really good example of javascript objects and their notation would be JSON.org
Here is an object that has 2 string properties, and a 3rd property which is an array. One slight difference is that because javascript is not strongly typed, the "residents" property could just be a simple string or an array. So you have to be careful when parsing as any property could be either a string or another array.
var household = {
address: "1234 N 56th st"
, city: "somewhere"
, residents: [
{ Name: "My Name" }
, { Name: "My Alias" }
]
};
Now depending on how you are sourcing the data, you can use the javascript or JSON (de)serialize methods within C# to populate.
Working with the data object below, I'm trying to write a function which takes in a name (the name being a label from the data, like in this case "GD"), and value. I want to use the function I have written below in underscore but I'm having a hard time trying to figure out how to write out this code, as I'm new to JS in general. Any input on how to modify the function getOption()?
var data = [{},{},
{
field:"ran",
indexable:true,
label:"R",
options: [
{},{},
{
category_value:"200",
label:"GD"
},{},{}
]
},{}
]
function getOption (name, value) {
return _.findWhere(data.options, {label: name}); //return the category_value of the name, if "GD" is the name, the output of this function should be 200
}
According to the docs,
_.findWhere(list, properties)
Looks through the list and
returns the first value that matches all of the key-value pairs listed
in properties.
If no match is found, or if list is empty, undefined will be returned.
_.findWhere(publicServicePulitzers, {newsroom: "The New York Times"});
=> {year: 1918, newsroom: "The New York Times", reason: "For its public service in publishing in full so many official reports,
documents and speeches by European statesmen relating to the progress
and conduct of the war."}
Looks like you have to specify the property name, and property value. In this case, "label" and "GD" respectively.
Try this:
var data = [{},{},
{
field:"ran",
indexable:true,
label:"R",
options: [
{},{},
{
category_value:"200",
label:"GD"
},{},{} // why so many initalized empty arrays?
]
},{}
]
function getOption (name, value) {
return _.findWhere(data.options, {label: "GD"}); // returns the whole array
// try var result = _.findWhere(data.options, {label: "GD"});
// then return result.category_value;
}
Just recommended the following url to somewhat related post. It might be of use for you, and it doesn't use an additional library: dynamic access to an array in javascript