JS Using objects dinamic keynames - javascript

I need to use object which contains my settings, mainly keynames assignment. But I cant figure out why it does not work
//This is my object which contains names of the keys of another object
let setup={
param1:'data1',
param2: 'data2'
}
//So here is the main object where I need to use values as a keynames
const StatDataObj = {
DataFields: {
['setup.param1']: {Blocks: [],Patch: []},
['setup.param1']: {Blocks: [],Patch: []}
}
}
Everything seems quite simple but it gives me error! So what im doing wrong?

Try this:
const setup = { param1:'data1', param2: 'data2' };
const StatDataObj = {
DataFields: {
[setup.param1]: { Blocks: [], Patch: [] },
[setup.param2]: { Blocks: [], Patch: [] }
}
};
console.log(StatDataObj);

The problem is that you adding string, not variable value
//This is my object which contains names of the keys of another object
let setup={
param1:'data1',
param2: 'data2'
}
//So here is the main object where I need to use values as a keynames
const StatDataObj = {
DataFields: {
[setup.param1]: {Blocks: [],Patch: []},
[setup.param1]: {Blocks: [],Patch: []}
}
}
console.log(StatDataObj)

Related

how to transform value string in object to new const js

i need to convert a object with have key value to new object that contain new const named form platform and have name to value in js how to do it?
posters: [
{ platform: facebook; name: ["user test1","user test2"] },
{ platform: instagram; name: ["Ig test1","Ig test2"] },
]
in to
posters: {
facebook: ["user test1","user test2"] ,
instagram: ["Ig test1","Ig test2"] ,
}
Your input array is invalid. There are no strings around your platform values, and you're separating your object properties with a semi-colon rather than a comma. So you would need to fix that in order to proceed.
It looks as if posters is a property within a larger object so this answer will take that into account.
Use reduce on the posters array to iterate over the objects in the array and return an object where the keys are the platform names, and the values the name arrays.
Since it looks like posters is within a larger object we'll rebuild the object using the spread syntax.
const data={posters:[{platform:"facebook",name:["user test1","user test2"]},{platform:"instagram",name:["Ig test1","Ig test2"]}]};
// Create a new object
const updated = {
// Spread out the old object into it
...data,
// And replace the old `posters` property with an
// object using `reduce`. Destructure the `platform`
// and `name` properties from the object, and then
// use them to add a key and a value to the initial
// object (`acc`/accumulator)
posters: data.posters.reduce((acc, obj) => {
const { platform, name } = obj;
acc[platform] = name;
return acc;
}, {})
};
console.log(updated);
Additional documentation
Destructuring assignment
const postersArray = [
{ platform: facebook, name: ["user test1","user test2"] },
{ platform: instagram, name: ["Ig test1","Ig test2"] }
]
const postersObject = postersArray.reduce((previous, current) => {
return {
…previous,
[current.platform]: current.name
}
},{})

Access and extract values from doubly nested array of objects in JavaScript

I have an array of objects and within those objects is another object which contains a particular property which I want to get the value from and store in a separate array.
How do I access and store the value from the name property from the data structure below:
pokemon:Object
abilities:Array[2]
0:Object
ability:Object
name:"blaze"
1:Object
ability:Object
name:"solar-power"
How would I return and display the values in the name property as a nice string like
blaze, solar-power ?
I tried doing something like this but I still get an array and I don't want to do a 3rd loop since that is not performant.
let pokemonAbilities = [];
let test = pokemon.abilities.map((poke) =>
Object.fromEntries(
Object.entries(poke).map(([a, b]) => [a, Object.values(b)[0]])
)
);
test.map((t) => pokemonAbilities.push(t.ability));
Sample Data:
"pokemon": {
"abilities": [
{
"ability": {
"name": "friend-guard",
"url": "https://pokeapi.co/api/v2/ability/132/"
},
"ability": {
"name": "Solar-flare",
"url": "https://pokeapi.co/api/v2/ability/132/"
}
}
]
}
Then I am doing a join on the returned array from above to get a formatted string.
It just seems like the multiple map() loops can be optimized but I am unsure how to make it more efficient.
Thank you.
There is no need for a loop within loop. Try this:
const pokemon = {
abilities: [{
ability: {
name: 'friend-guard',
url: 'https://pokeapi.co/api/v2/ability/132/'
},
}, {
ability: {
name: 'Solar-flare',
url: 'https://pokeapi.co/api/v2/ability/132/'
}
}]
};
const pokemonAbilities = pokemon.abilities.map(item => item.ability.name).join(', ');
console.log(pokemonAbilities);

Prevent prop from overwriting the data

I'm new to vue.js and struggling with the following scenario.
I send an array filled with objects via props to my router-view.
Inside one of my router-view components I use this array in multiple functions, reference it with 'this.data' and safe it inside the functions in a new variable so I don't overwrite the actual prop data.
However the functions overwrite the original prop data and manipulate the data of the prop.
Here is an abstract example of my question:
App.vue
<template>
<div>
<router-view :data='data'></router-view>
</div>
</template>
<script>
export default {
data: function() {
return {
data: [],
};
},
created: function() {
this.getData();
},
methods: {
getData: function() {
this.data = // array of objects
},
}
route component:
<script>
export default {
props: {
data: Array,
},
data: function() {
return {
newData1 = [],
newData2 = [],
}
}
created: function() {
this.useData1();
this.useData2();
},
methods: {
useData1: function() {
let localData = this.data;
// do something with 'localData'
this.newData1 = localData;
}
useData2: function() {
let localData = this.data;
// do something with 'localData'
this.newData2 = localData;
}
}
}
</script>
The 'localData' in useData2 is manipulated from changes in useData1, whereby I don't overwrite the data prop.
Why do I overwrite the prop and how can i prevent it?
The problem you're experiencing a side effect of copying this.data by reference, rather than value.
The solution is to use a technique commonly referred to as cloning. Arrays can typically be cloned using spread syntax or Array.from().
See below for a practical example.
// Methods.
methods: {
// Use Data 1.
useData1: function() {
this.newData1 = [...this.data]
},
// Use Data 2.
useData2: function() {
this.newData2 = Array.from(this.data)
}
}
#Arman Charan is right on his answer. Object and arrays are not primitive types but reference.
There is an awesome video explanation here => JavaScript - Reference vs Primitive Values/ Types
So for reference types you first have to clone it on another variable and later modify this variable without the changes affecting the original data.
However for nested arrays and objects in high level the spead and Array.from will not work.
If you are using Lodash you can use _.cloneDeep() to clone an array or an object safely.
I like functional programming and I use Lodash which I strongly recommend.
So you can do:
let original_reference_type = [{ id:1 }, { id: 2 }]
let clone_original = _.cloneDeep(original_reference_type)
clone_original[0].id = "updated"
console.log(original_reference_type) //[{ id:1 }, { id: 2 }] => will not change
console.log(clone_original) // [{ id: "updated" }, { id: 2 }]
Suggestion: For simple arrays and objects use:
Objects:
let clone_original_data = {...original_data} or
let clone_original_data = Object.assign({}, original_data)
Arrays:
let clone_original_data = [...original_data] or
let clonse_original_data = original_data.slice()
For complex and high nested arrays or Objects go with Lodash's _.cloneDeep()
I think this is most readable, "declarative" way:
First, install lodash npm i lodash. Then import desired function, not the whole library, and initialize your data with array from props.
<script>
import cloneDeep from 'lodash/cloneDeep'
export default {
props: {
data: Array
},
data () {
return {
// initialize once / non reactive
newData1: cloneDeep(this.data),
newData2: cloneDeep(this.data)
}
}
}
</script>

Why are these methods disappearing when I clone the array? [duplicate]

This question already has answers here:
What is the most efficient way to deep clone an object in JavaScript?
(67 answers)
Closed 4 years ago.
For some strange reason, when this data:
// data
visitorsTemplate: [{
text: '',
type: 'buttons',
children: [{
name: 'email',
method: (e) => { this.sendEmail(e) }
}]
}]
Is cloned:
// watch
console.log(this.visitorsTemplate)
const visitorItem = clone(this.visitorsTemplate)
console.log(visitorItem)
With this function:
// utils
export const clone = (...args) => {
return JSON.parse(JSON.stringify.apply(null, args))
}
the method attribute disappears. Here are the console.logs:
[{
text: "",
type: "buttons",
children": [{
name: "email",
method: f method(e)
}, {
name: "delete",
method: f method(e)
}]
}]
[{
text: "",
type: "buttons",
children": [{
name: "email"
}, {
name: "delete"
}]
}]
Update: I found out JSON.stringify is removing the methods but I need to create a new array. So how to avoid removing the methods?
You can implement your own deep clone implmentaion of object. Try this code.
function deepcloneObject(obj) {
var clone = {};
for(var i in obj) {
if(obj[i] != null && typeof(obj[i])=="object")
clone[i] = deepcloneObject(obj[i]);
else
clone[i] = obj[i];
}
return clone;
}
If you check the JSON Specs here , you will notice that there is no specification for a JSON to contain methods and it contains only data. When you do stringify and then parse, you are taking intermediate step as JSON which is causing this.
For a more detailed account on cloning array of objects, please refer this post.
Hope this helps!
the moment you do JSON.stringify, they will try to create a string of your JSON object. when you have method inside, it will try to convert to string also.
So, if you want to have a new instance of object you can use this: http://underscorejs.org/#clone
newObject = _.clone(visitor)
or if you want to be able to create programatically later, you prepare these:
function Visitor(){
return {
text: '',
type: 'buttons',
children: [Child()]
}
}
function Child(){
return {
name: 'email',
method: (e) => { this.sendEmail(e) }
}
}
Use Object.assign along with Array.prototype.map
const clonedArray = array.map(a => Object.assign({}, a));

how to reach a property in nested objects easily?

I have a nested object. here it is:
var Obj = {
a: {
state: {
started: false,
players: [],
hand: 0,
totalHand: 0,
teams: {
starter: {
name: "",
handPoints: [],
totalPoint: calc(Obj.a.state.teams.starter.handPoints)
}
}
}
}
};
Like you see , i need to use handPoints value to set totalPoint. Do i have to call that like this:
calc(Obj.a.state.teams.starter.handPoints)
is there some way about using this keyword or something else?
What if i had a more nested object? It looks like weird to me.
Thank you.
Have you tried your solution? It causes a syntax error. Obj isn't defined while you're trying to define it, and even if it was you wouldn't get the latest value of obj, because you're trying to set it as the current value of the array at runtime.
see here:
syntax error example
You want to make that property a function so that a user can get the current total when they access the function.
Like this:
totalPoint: function(){
return calc(Obj.a.state.teams.starter.handPoints)
}
working example
If you want to shorten the reference you can alias some part of it. For instance
totalPoint: function(){
var myStarter = Obj.a.state.teams.starter;
return calc(myStarter.handPoints)
}
You could instead make the variable totalPoint into a function and use this.
var Obj = {
a: {
state: {
started: false,
players: [],
hand: 0,
totalHand: 0,
teams: {
starter: {
name: "",
handPoints: [ 5,6 ],
totalPoints: function() {
return calc(this.handPoints);
}
}
}
}
}
};
Here is the jsFiddle example.

Categories

Resources