Create object mapping via dot walking which is a string [duplicate] - javascript

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 2 years ago.
I make a call to downstream and receive a response something like
// for sake of ease, let's call this variable as resp
{
"data":{
"abc": {
"value":"Hi there",
"timestamp":"xxxxxxxxxx"
}
}
}
I then need to access resp.data.abc.value but the problem is that I've to do it dynamically (i.e. the data.abc.value part is coming from database)
So the flow of my program is something like this:
/*
(a) Make a REST call
(b) Receive the response, assign it to a variable named "resp"
(c) Grab the dot walking path from db
(d) DB result will be "data.abc.value" and type will be a string
(e) Figure out a way to split the DB result and apply it on the "resp" variablevalue
*/
I've tried using .split() and iterating through a loop but it's getting quite messy and complex to understand.

You could use .reduce for splited dot paths, tricky path here is to handle non-existed path, but it could be solved by using default value
const getByDotPath = (path = "", object = {}) => {
return path
.split(".")
.reduce((iteratee = {}, p) => iteratee[p], object)
}
const getByDotPath = (path = "", object = {}) => {
return path
.split(".")
.reduce((iteratee = {}, p) => iteratee[p], object)
}
const resp = {
data: {
abc: {
value: "Hi there",
timestamp: "xxxxxxxxxx",
},
},
}
console.log(getByDotPath("data.abc.value", resp))
console.log(getByDotPath("data.abc.value.def", resp))

You can use lodash's get:
const data = _.get(resp, "data.abc.value");

Related

Turning an array into array of objects but cannot run function [duplicate]

This question already has answers here:
Why can I not use the spread operator on a class function?
(3 answers)
Copy prototype for inheritance?
(2 answers)
Closed 25 days ago.
Alright, I must be missing something here. I have an object:
export class Country {
id: number = 0
name: string = ''
getNamePlusBob() {
return this.name + 'bob'
}
}
And I get the data from an API in an array, then pass it to the browser.
Once i have the data I want to turn the array into an array of objects of type 'Country'.
So I made this function (not sure if Hydrate is the correct term here?):
function hydrateArray(data, entity) {
let returnArray = []
console.log(data)
data.forEach((row) => {
const object = entity;
for (const [key, value] of Object.entries(row)) {
if(Object.hasOwn(object, key)) {
object[key] = value
} else {
console.log('Key not found in entity', key)
}
}
console.log(object.getNamePlusBob())
returnArray.push({...object})
})
return returnArray
}
const countries = hydrateArray(countryData, new Country())
In the console.log in the function, I can run the getNamePlusBob() and it returns the name plus bob. However, on the returned array countries, I cannot:
console.log(countries[0].getNamePlusBob())
TypeError: countries[0].getNamePlusBob is not a function
Why not? It was inside the hydrateArray function, why cant I run it outside?

Rename object keys of return object [duplicate]

This question already has an answer here:
ES6/ES2015 object destructuring and changing target variable
(1 answer)
Closed 1 year ago.
Szenario
A method matter returns an object, like return {content, data}
Conflict
The second call of the method (a method from a node module) overwrites previous vars set from return.
import matter from 'gray-matter'
const test = () => {
...
const { content, data } = matter(source1)
const { content, data } = matter(source2) // this overwrites previous content, data vars
...
}
Goal / Question
Setting the return values in different named vars, like:
const { content2, data2 } = matter(source2) // like so it leads to an compiling error property content2 does not exists on type [...]
So, how can be the return values assigned to different named vars as they are named in the type?
Just use different variable names:
const { content, data } = matter(source1)
const { content: content2, data: data2 } = matter(source2)
Or don't destructure at all:
const result1 = matter(source1)
const result2 = matter(source2)
Or use an array of objects:
const results = [source1, source2].map(matter);

How to find complex objects in an Object from a String (these have to be separeted with dots) - Angular - [duplicate]

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 3 years ago.
I hope you are very well.
I am trying to find an complex object in an Object in Angular from a String (the content of this String is dynamic).
For example:
let variable = {
"name":"Rick",
"family": {
"son":"Andy"
}
};
When I try to read the name attribute, I can find it with the code:
console.log(variable["name"]);
When I try to read the family attribute, I can find it with the code:
console.log(variable["family"]);
However when I try to read the son attribute, I have tried to make with the code:
console.log(variable["family.son"]);
But I have gotten an undefined value, I found that I can use any of the followings codes:
console.log(variable["family"]["son"]);
console.log(variable["family"].son);
But it is not working for me, because I need to search the attribute from a String (the attributes are Dynamics), Does someone know how can I solve this.
The String contains the attribute path, for instance: "family.son" or "family"
Regards.
Try something like this:
const dotPathAccessor = (src, path) => {
const parts = path.split('.');
return parts.reduce((obj, prop) => obj[prop], src);
}
const variable = {
"name": "Rick",
"family": {
"son": "Andy"
}
};
console.log(dotPathAccessor(variable, "family.son"));
// you can use a Proxy object to make it simpler
// with this prototype, you can now get a dot proxy for any object using `object.getDotProxy`
// and access it using dot paths
Object.prototype.getDotProxy = () => new Proxy(variable, {
get(obj, prop) {
return dotPathAccessor(obj, prop);
}
});
const dotProxy = variable.getDotProxy();
console.log(dotProxy["family.son"]);

Get second level value from an object with a variable [duplicate]

This question already has answers here:
Accessing nested JavaScript objects and arrays by string path
(44 answers)
Closed 7 years ago.
I am making a function where i give the object path in a variable. I use this function after i got my data from the database.
function find(object, path, cb) {
return cb(object[path]);
}
var object = {user:{firstname:"bob"}};
find(object, "user", function(data){});
This works fine with objects on the first level of the object but what if i want a object from the second level or higher:
"user.firstname"
When i try to run this through the find function wil it give a not defined error. How can i improve my function?
You can do it manually by split function and iteratively executing this pattern:
var properties = path.split(".");
var value = obj;
for(prop of properties)
{
value = value[prop];
}
You could make your find function recursive. Besides making the path an array instead of a string gives you the option to do this for multiple layers.
function find (object, path, cb) {
if (path.length > 1) return find(object[path.shift()], path, cb);
return cb(object[path.pop()]);
}
var object = {user: {firstname:"bob"}};
find(object, ["user","firstname"], function (data){console.log(data)});

Creating object with dynamic keys [duplicate]

This question already has answers here:
How to use a variable for a key in a JavaScript object literal?
(16 answers)
Closed 8 years ago.
First off, I'm using Cheerio for some DOM access and parsing with Node.js. Good times.
Heres the situation:
I have a function that I need to create an object. That object uses variables for both its keys and values, and then return that single object. Example:
stuff = function (thing, callback) {
var inputs = $('div.quantity > input').map(function(){
var key = this.attr('name')
, value = this.attr('value');
return { key : value }
})
callback(null, inputs);
}
It outputs this:
[ { key: '1' }, { key: '1' } ]
(.map() returns an array of objects fyi)
I need key to actually be the string from this.attr('name').
Whats the best way to assign a string as a key in Javascript, considering what I'm trying to do?
In the new ES2015 standard for JavaScript (formerly called ES6), objects can be created with computed keys: Object Initializer spec.
The syntax is:
var obj = {
[myKey]: value,
}
If applied to the OP's scenario, it would turn into:
stuff = function (thing, callback) {
var inputs = $('div.quantity > input').map(function(){
return {
[this.attr('name')]: this.attr('value'),
};
})
callback(null, inputs);
}
Note: A transpiler is still required for browser compatiblity.
Using Babel or Google's traceur, it is possible to use this syntax today.
In earlier JavaScript specifications (ES5 and below), the key in an object literal is always interpreted literally, as a string.
To use a "dynamic" key, you have to use bracket notation:
var obj = {};
obj[myKey] = value;
In your case:
stuff = function (thing, callback) {
var inputs = $('div.quantity > input').map(function(){
var key = this.attr('name')
, value = this.attr('value')
, ret = {};
ret[key] = value;
return ret;
})
callback(null, inputs);
}
You can't define an object literal with a dynamic key. Do this :
var o = {};
o[key] = value;
return o;
There's no shortcut (edit: there's one now, with ES6, see the other answer).

Categories