Get string representation of object path
Say I have a situation like this:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
and then I have:
const stew = {
moo: () => foo.bar.star.guitar
}
then I call moo in the next tick of the event loop:
process.nextTick(function(){
const guitar = stew.moo();
});
my question is - is there any way/trick to get the string representation of the path: "foo.bar.star.guitar"?
I could replace the code with a string:
const stew = {
moo: () => 'foo.bar.star.guitar'
}
but I am looking to find a way to get a string representation.
One important detail is that I want to generate a useful error message - if someone puts in an object path that doesn't exist. That is the whole purpose of getting a string representation - for a useful error message.
javascript node.js
add a comment |
Say I have a situation like this:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
and then I have:
const stew = {
moo: () => foo.bar.star.guitar
}
then I call moo in the next tick of the event loop:
process.nextTick(function(){
const guitar = stew.moo();
});
my question is - is there any way/trick to get the string representation of the path: "foo.bar.star.guitar"?
I could replace the code with a string:
const stew = {
moo: () => 'foo.bar.star.guitar'
}
but I am looking to find a way to get a string representation.
One important detail is that I want to generate a useful error message - if someone puts in an object path that doesn't exist. That is the whole purpose of getting a string representation - for a useful error message.
javascript node.js
add a comment |
Say I have a situation like this:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
and then I have:
const stew = {
moo: () => foo.bar.star.guitar
}
then I call moo in the next tick of the event loop:
process.nextTick(function(){
const guitar = stew.moo();
});
my question is - is there any way/trick to get the string representation of the path: "foo.bar.star.guitar"?
I could replace the code with a string:
const stew = {
moo: () => 'foo.bar.star.guitar'
}
but I am looking to find a way to get a string representation.
One important detail is that I want to generate a useful error message - if someone puts in an object path that doesn't exist. That is the whole purpose of getting a string representation - for a useful error message.
javascript node.js
Say I have a situation like this:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
and then I have:
const stew = {
moo: () => foo.bar.star.guitar
}
then I call moo in the next tick of the event loop:
process.nextTick(function(){
const guitar = stew.moo();
});
my question is - is there any way/trick to get the string representation of the path: "foo.bar.star.guitar"?
I could replace the code with a string:
const stew = {
moo: () => 'foo.bar.star.guitar'
}
but I am looking to find a way to get a string representation.
One important detail is that I want to generate a useful error message - if someone puts in an object path that doesn't exist. That is the whole purpose of getting a string representation - for a useful error message.
javascript node.js
javascript node.js
edited Nov 23 '18 at 8:48
Alexander Mills
asked Nov 22 '18 at 23:41
Alexander MillsAlexander Mills
18.8k32154317
18.8k32154317
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
One approach could be to use a reducer to extract the value from a supplied path. For a path such as bar.star.guitar
, you could extract the value geetar
from object:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
via the following:
const path = 'bar.star.guitar'; // Remove "foo" from your path
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
const value = path
.split('.') // Break path into parts, splitting by '.'
.reduce((currentObject, pathPart) => {
// Iterate through each part of the path in order, and incrementally
// extract and return corresponding value of currentObject if it
// exists. Repeat this for each path part until we find value from
// input object at end of the path
if(currentObject) {
currentObject = currentObject[ pathPart ]
}
return currentObject
}, foo);
console.log('path: ', path, 'value:', value)
The idea here is to iterate in order through each "part" (ie string separated by '.') of the input path, and incrementally extract and return the value corresponding to the part (key) of the input object being processed. We incrementally continue this process until the end of the path is reached, at which point we arrive at the desired value (if it exists)
I don't understand this answer - I don't have'foo.bar.star.guitar'
as a string. I don't have that info. All I know is whether the object resolved or it threw an error "cannot read property x of undefined'.
– Alexander Mills
Nov 23 '18 at 0:10
@AlexanderMills right - so you have some arbitrary path string, and you need to extract the value corresponding to that path from input object? The snippet above is intended to illustrate how this can be done in general terms. Also, something to be aware of is that the pathfoo.bar.star.guitar
is actually invalid for the objectfoo
in your OP. Is there a format that you would prefer this answer to be presented in?
– Dacre Denny
Nov 23 '18 at 0:37
1
Your answer is how to resolve foo.bar.star.guitar from 'foo.bar.star.guitar'. But the question is about how to infer 'foo.bar.star.guitar' from foo.bar.star.guitar, for generating error messages for improper object access.
– Lauren
Nov 23 '18 at 7:34
add a comment |
const stew = {
moo: () => foo.bar.star.guitar
}
stew.moo.toString().match(/([a-z0-9_$]+.?)+/)[0]
// returns "foo.bar.star.guitar"
This somewhat depends on people always using the same kind of function. Also I just used a short-hand for valid function name - the actual regex would be much longer.. What characters are valid for JavaScript variable names?
sure if you can create a good regex to extract the string from the arrow function, that'd be useful.
– Alexander Mills
Nov 23 '18 at 0:13
add a comment |
This is for a library, so I won't have any other information besides:
const stew = {
moo: () => foo.bar.star.guitar
}
so one thing I can do is:
let guitar;
try{
guitar = stew.moo();
}
catch(err){
console.error('Could not get value from:', stew.moo.toString());
}
aka, just log the string representation of the function. This is good enough information for the user to have to debug the problem.
For a full demo see:
https://gist.github.com/ORESoftware/5a1626037cb8ba568cdffa69374eac1d
add a comment |
based on your comments about this being for useful error messages, I believe you can get away with Error.captureStackTrace
const er = {};
Error.captureStackTrace(er);
const foo = {
bar: {
star: {
guitar: "geetar"
}
}
};
const a = foo.bar.nope.guitar;
console.log(er.stack);
which logs
const a = foo.bar.nope.guitar;
^
add a comment |
If you are able to control the root variables that people can refer to, you could wrap them in a Proxy object which tracks the property access all the way down, like so:
function callStackTracker(propsSoFar) {
return {
get: function(obj, prop) {
if (prop in obj) {
return typeof obj[prop] === "object" ?
new Proxy(obj[prop], callStackTracker(propsSoFar.concat(prop))) :
obj[prop];
} else {
throw new Error("Couldn't resolve: " + propsSoFar.concat(prop).join('.'));
}
}
};
};
let foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
foo = new Proxy(foo, callStackTracker(['foo']));
console.log(foo.bar.star.guitar); // "geetar"
console.log(foo.bar.star.clarinet); // Error: Couldn't resolve: foo.bar.star.clarinet
console.log(foo.bar.boat); // Error: Couldn't resolve: foo.bar.boat
I am then throwing this resolved path as an error in this example, but you could do whatever you like with it.
this would work, but I want to log the full path, not just the point where it failed. Proxy objects are cool tho.
– Alexander Mills
Nov 23 '18 at 9:44
Not sure I get you - it does give the full path
– Lauren
Nov 23 '18 at 11:08
You have 3 console.log output lines, they arent showing the full path, only shows where it failed. For example if it failed at bar it would say could not resolvefoo.bar
– Alexander Mills
Nov 23 '18 at 20:50
1
Ah yes I get you now! Hmm, needs more thought.
– Lauren
Nov 24 '18 at 0:48
Any new ideas on this front? thx. This answer is fine, just leave it.
– Alexander Mills
Nov 29 '18 at 21:17
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53439136%2fget-string-representation-of-object-path%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
One approach could be to use a reducer to extract the value from a supplied path. For a path such as bar.star.guitar
, you could extract the value geetar
from object:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
via the following:
const path = 'bar.star.guitar'; // Remove "foo" from your path
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
const value = path
.split('.') // Break path into parts, splitting by '.'
.reduce((currentObject, pathPart) => {
// Iterate through each part of the path in order, and incrementally
// extract and return corresponding value of currentObject if it
// exists. Repeat this for each path part until we find value from
// input object at end of the path
if(currentObject) {
currentObject = currentObject[ pathPart ]
}
return currentObject
}, foo);
console.log('path: ', path, 'value:', value)
The idea here is to iterate in order through each "part" (ie string separated by '.') of the input path, and incrementally extract and return the value corresponding to the part (key) of the input object being processed. We incrementally continue this process until the end of the path is reached, at which point we arrive at the desired value (if it exists)
I don't understand this answer - I don't have'foo.bar.star.guitar'
as a string. I don't have that info. All I know is whether the object resolved or it threw an error "cannot read property x of undefined'.
– Alexander Mills
Nov 23 '18 at 0:10
@AlexanderMills right - so you have some arbitrary path string, and you need to extract the value corresponding to that path from input object? The snippet above is intended to illustrate how this can be done in general terms. Also, something to be aware of is that the pathfoo.bar.star.guitar
is actually invalid for the objectfoo
in your OP. Is there a format that you would prefer this answer to be presented in?
– Dacre Denny
Nov 23 '18 at 0:37
1
Your answer is how to resolve foo.bar.star.guitar from 'foo.bar.star.guitar'. But the question is about how to infer 'foo.bar.star.guitar' from foo.bar.star.guitar, for generating error messages for improper object access.
– Lauren
Nov 23 '18 at 7:34
add a comment |
One approach could be to use a reducer to extract the value from a supplied path. For a path such as bar.star.guitar
, you could extract the value geetar
from object:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
via the following:
const path = 'bar.star.guitar'; // Remove "foo" from your path
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
const value = path
.split('.') // Break path into parts, splitting by '.'
.reduce((currentObject, pathPart) => {
// Iterate through each part of the path in order, and incrementally
// extract and return corresponding value of currentObject if it
// exists. Repeat this for each path part until we find value from
// input object at end of the path
if(currentObject) {
currentObject = currentObject[ pathPart ]
}
return currentObject
}, foo);
console.log('path: ', path, 'value:', value)
The idea here is to iterate in order through each "part" (ie string separated by '.') of the input path, and incrementally extract and return the value corresponding to the part (key) of the input object being processed. We incrementally continue this process until the end of the path is reached, at which point we arrive at the desired value (if it exists)
I don't understand this answer - I don't have'foo.bar.star.guitar'
as a string. I don't have that info. All I know is whether the object resolved or it threw an error "cannot read property x of undefined'.
– Alexander Mills
Nov 23 '18 at 0:10
@AlexanderMills right - so you have some arbitrary path string, and you need to extract the value corresponding to that path from input object? The snippet above is intended to illustrate how this can be done in general terms. Also, something to be aware of is that the pathfoo.bar.star.guitar
is actually invalid for the objectfoo
in your OP. Is there a format that you would prefer this answer to be presented in?
– Dacre Denny
Nov 23 '18 at 0:37
1
Your answer is how to resolve foo.bar.star.guitar from 'foo.bar.star.guitar'. But the question is about how to infer 'foo.bar.star.guitar' from foo.bar.star.guitar, for generating error messages for improper object access.
– Lauren
Nov 23 '18 at 7:34
add a comment |
One approach could be to use a reducer to extract the value from a supplied path. For a path such as bar.star.guitar
, you could extract the value geetar
from object:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
via the following:
const path = 'bar.star.guitar'; // Remove "foo" from your path
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
const value = path
.split('.') // Break path into parts, splitting by '.'
.reduce((currentObject, pathPart) => {
// Iterate through each part of the path in order, and incrementally
// extract and return corresponding value of currentObject if it
// exists. Repeat this for each path part until we find value from
// input object at end of the path
if(currentObject) {
currentObject = currentObject[ pathPart ]
}
return currentObject
}, foo);
console.log('path: ', path, 'value:', value)
The idea here is to iterate in order through each "part" (ie string separated by '.') of the input path, and incrementally extract and return the value corresponding to the part (key) of the input object being processed. We incrementally continue this process until the end of the path is reached, at which point we arrive at the desired value (if it exists)
One approach could be to use a reducer to extract the value from a supplied path. For a path such as bar.star.guitar
, you could extract the value geetar
from object:
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
via the following:
const path = 'bar.star.guitar'; // Remove "foo" from your path
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
const value = path
.split('.') // Break path into parts, splitting by '.'
.reduce((currentObject, pathPart) => {
// Iterate through each part of the path in order, and incrementally
// extract and return corresponding value of currentObject if it
// exists. Repeat this for each path part until we find value from
// input object at end of the path
if(currentObject) {
currentObject = currentObject[ pathPart ]
}
return currentObject
}, foo);
console.log('path: ', path, 'value:', value)
The idea here is to iterate in order through each "part" (ie string separated by '.') of the input path, and incrementally extract and return the value corresponding to the part (key) of the input object being processed. We incrementally continue this process until the end of the path is reached, at which point we arrive at the desired value (if it exists)
const path = 'bar.star.guitar'; // Remove "foo" from your path
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
const value = path
.split('.') // Break path into parts, splitting by '.'
.reduce((currentObject, pathPart) => {
// Iterate through each part of the path in order, and incrementally
// extract and return corresponding value of currentObject if it
// exists. Repeat this for each path part until we find value from
// input object at end of the path
if(currentObject) {
currentObject = currentObject[ pathPart ]
}
return currentObject
}, foo);
console.log('path: ', path, 'value:', value)
const path = 'bar.star.guitar'; // Remove "foo" from your path
const foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
const value = path
.split('.') // Break path into parts, splitting by '.'
.reduce((currentObject, pathPart) => {
// Iterate through each part of the path in order, and incrementally
// extract and return corresponding value of currentObject if it
// exists. Repeat this for each path part until we find value from
// input object at end of the path
if(currentObject) {
currentObject = currentObject[ pathPart ]
}
return currentObject
}, foo);
console.log('path: ', path, 'value:', value)
edited Nov 22 '18 at 23:58
answered Nov 22 '18 at 23:48
Dacre DennyDacre Denny
11.7k41031
11.7k41031
I don't understand this answer - I don't have'foo.bar.star.guitar'
as a string. I don't have that info. All I know is whether the object resolved or it threw an error "cannot read property x of undefined'.
– Alexander Mills
Nov 23 '18 at 0:10
@AlexanderMills right - so you have some arbitrary path string, and you need to extract the value corresponding to that path from input object? The snippet above is intended to illustrate how this can be done in general terms. Also, something to be aware of is that the pathfoo.bar.star.guitar
is actually invalid for the objectfoo
in your OP. Is there a format that you would prefer this answer to be presented in?
– Dacre Denny
Nov 23 '18 at 0:37
1
Your answer is how to resolve foo.bar.star.guitar from 'foo.bar.star.guitar'. But the question is about how to infer 'foo.bar.star.guitar' from foo.bar.star.guitar, for generating error messages for improper object access.
– Lauren
Nov 23 '18 at 7:34
add a comment |
I don't understand this answer - I don't have'foo.bar.star.guitar'
as a string. I don't have that info. All I know is whether the object resolved or it threw an error "cannot read property x of undefined'.
– Alexander Mills
Nov 23 '18 at 0:10
@AlexanderMills right - so you have some arbitrary path string, and you need to extract the value corresponding to that path from input object? The snippet above is intended to illustrate how this can be done in general terms. Also, something to be aware of is that the pathfoo.bar.star.guitar
is actually invalid for the objectfoo
in your OP. Is there a format that you would prefer this answer to be presented in?
– Dacre Denny
Nov 23 '18 at 0:37
1
Your answer is how to resolve foo.bar.star.guitar from 'foo.bar.star.guitar'. But the question is about how to infer 'foo.bar.star.guitar' from foo.bar.star.guitar, for generating error messages for improper object access.
– Lauren
Nov 23 '18 at 7:34
I don't understand this answer - I don't have
'foo.bar.star.guitar'
as a string. I don't have that info. All I know is whether the object resolved or it threw an error "cannot read property x of undefined'.– Alexander Mills
Nov 23 '18 at 0:10
I don't understand this answer - I don't have
'foo.bar.star.guitar'
as a string. I don't have that info. All I know is whether the object resolved or it threw an error "cannot read property x of undefined'.– Alexander Mills
Nov 23 '18 at 0:10
@AlexanderMills right - so you have some arbitrary path string, and you need to extract the value corresponding to that path from input object? The snippet above is intended to illustrate how this can be done in general terms. Also, something to be aware of is that the path
foo.bar.star.guitar
is actually invalid for the object foo
in your OP. Is there a format that you would prefer this answer to be presented in?– Dacre Denny
Nov 23 '18 at 0:37
@AlexanderMills right - so you have some arbitrary path string, and you need to extract the value corresponding to that path from input object? The snippet above is intended to illustrate how this can be done in general terms. Also, something to be aware of is that the path
foo.bar.star.guitar
is actually invalid for the object foo
in your OP. Is there a format that you would prefer this answer to be presented in?– Dacre Denny
Nov 23 '18 at 0:37
1
1
Your answer is how to resolve foo.bar.star.guitar from 'foo.bar.star.guitar'. But the question is about how to infer 'foo.bar.star.guitar' from foo.bar.star.guitar, for generating error messages for improper object access.
– Lauren
Nov 23 '18 at 7:34
Your answer is how to resolve foo.bar.star.guitar from 'foo.bar.star.guitar'. But the question is about how to infer 'foo.bar.star.guitar' from foo.bar.star.guitar, for generating error messages for improper object access.
– Lauren
Nov 23 '18 at 7:34
add a comment |
const stew = {
moo: () => foo.bar.star.guitar
}
stew.moo.toString().match(/([a-z0-9_$]+.?)+/)[0]
// returns "foo.bar.star.guitar"
This somewhat depends on people always using the same kind of function. Also I just used a short-hand for valid function name - the actual regex would be much longer.. What characters are valid for JavaScript variable names?
sure if you can create a good regex to extract the string from the arrow function, that'd be useful.
– Alexander Mills
Nov 23 '18 at 0:13
add a comment |
const stew = {
moo: () => foo.bar.star.guitar
}
stew.moo.toString().match(/([a-z0-9_$]+.?)+/)[0]
// returns "foo.bar.star.guitar"
This somewhat depends on people always using the same kind of function. Also I just used a short-hand for valid function name - the actual regex would be much longer.. What characters are valid for JavaScript variable names?
sure if you can create a good regex to extract the string from the arrow function, that'd be useful.
– Alexander Mills
Nov 23 '18 at 0:13
add a comment |
const stew = {
moo: () => foo.bar.star.guitar
}
stew.moo.toString().match(/([a-z0-9_$]+.?)+/)[0]
// returns "foo.bar.star.guitar"
This somewhat depends on people always using the same kind of function. Also I just used a short-hand for valid function name - the actual regex would be much longer.. What characters are valid for JavaScript variable names?
const stew = {
moo: () => foo.bar.star.guitar
}
stew.moo.toString().match(/([a-z0-9_$]+.?)+/)[0]
// returns "foo.bar.star.guitar"
This somewhat depends on people always using the same kind of function. Also I just used a short-hand for valid function name - the actual regex would be much longer.. What characters are valid for JavaScript variable names?
edited Nov 23 '18 at 0:16
answered Nov 23 '18 at 0:13
LaurenLauren
1,2131129
1,2131129
sure if you can create a good regex to extract the string from the arrow function, that'd be useful.
– Alexander Mills
Nov 23 '18 at 0:13
add a comment |
sure if you can create a good regex to extract the string from the arrow function, that'd be useful.
– Alexander Mills
Nov 23 '18 at 0:13
sure if you can create a good regex to extract the string from the arrow function, that'd be useful.
– Alexander Mills
Nov 23 '18 at 0:13
sure if you can create a good regex to extract the string from the arrow function, that'd be useful.
– Alexander Mills
Nov 23 '18 at 0:13
add a comment |
This is for a library, so I won't have any other information besides:
const stew = {
moo: () => foo.bar.star.guitar
}
so one thing I can do is:
let guitar;
try{
guitar = stew.moo();
}
catch(err){
console.error('Could not get value from:', stew.moo.toString());
}
aka, just log the string representation of the function. This is good enough information for the user to have to debug the problem.
For a full demo see:
https://gist.github.com/ORESoftware/5a1626037cb8ba568cdffa69374eac1d
add a comment |
This is for a library, so I won't have any other information besides:
const stew = {
moo: () => foo.bar.star.guitar
}
so one thing I can do is:
let guitar;
try{
guitar = stew.moo();
}
catch(err){
console.error('Could not get value from:', stew.moo.toString());
}
aka, just log the string representation of the function. This is good enough information for the user to have to debug the problem.
For a full demo see:
https://gist.github.com/ORESoftware/5a1626037cb8ba568cdffa69374eac1d
add a comment |
This is for a library, so I won't have any other information besides:
const stew = {
moo: () => foo.bar.star.guitar
}
so one thing I can do is:
let guitar;
try{
guitar = stew.moo();
}
catch(err){
console.error('Could not get value from:', stew.moo.toString());
}
aka, just log the string representation of the function. This is good enough information for the user to have to debug the problem.
For a full demo see:
https://gist.github.com/ORESoftware/5a1626037cb8ba568cdffa69374eac1d
This is for a library, so I won't have any other information besides:
const stew = {
moo: () => foo.bar.star.guitar
}
so one thing I can do is:
let guitar;
try{
guitar = stew.moo();
}
catch(err){
console.error('Could not get value from:', stew.moo.toString());
}
aka, just log the string representation of the function. This is good enough information for the user to have to debug the problem.
For a full demo see:
https://gist.github.com/ORESoftware/5a1626037cb8ba568cdffa69374eac1d
edited Nov 23 '18 at 0:24
answered Nov 23 '18 at 0:10
Alexander MillsAlexander Mills
18.8k32154317
18.8k32154317
add a comment |
add a comment |
based on your comments about this being for useful error messages, I believe you can get away with Error.captureStackTrace
const er = {};
Error.captureStackTrace(er);
const foo = {
bar: {
star: {
guitar: "geetar"
}
}
};
const a = foo.bar.nope.guitar;
console.log(er.stack);
which logs
const a = foo.bar.nope.guitar;
^
add a comment |
based on your comments about this being for useful error messages, I believe you can get away with Error.captureStackTrace
const er = {};
Error.captureStackTrace(er);
const foo = {
bar: {
star: {
guitar: "geetar"
}
}
};
const a = foo.bar.nope.guitar;
console.log(er.stack);
which logs
const a = foo.bar.nope.guitar;
^
add a comment |
based on your comments about this being for useful error messages, I believe you can get away with Error.captureStackTrace
const er = {};
Error.captureStackTrace(er);
const foo = {
bar: {
star: {
guitar: "geetar"
}
}
};
const a = foo.bar.nope.guitar;
console.log(er.stack);
which logs
const a = foo.bar.nope.guitar;
^
based on your comments about this being for useful error messages, I believe you can get away with Error.captureStackTrace
const er = {};
Error.captureStackTrace(er);
const foo = {
bar: {
star: {
guitar: "geetar"
}
}
};
const a = foo.bar.nope.guitar;
console.log(er.stack);
which logs
const a = foo.bar.nope.guitar;
^
answered Nov 23 '18 at 0:38
rlemonrlemon
13.7k1077115
13.7k1077115
add a comment |
add a comment |
If you are able to control the root variables that people can refer to, you could wrap them in a Proxy object which tracks the property access all the way down, like so:
function callStackTracker(propsSoFar) {
return {
get: function(obj, prop) {
if (prop in obj) {
return typeof obj[prop] === "object" ?
new Proxy(obj[prop], callStackTracker(propsSoFar.concat(prop))) :
obj[prop];
} else {
throw new Error("Couldn't resolve: " + propsSoFar.concat(prop).join('.'));
}
}
};
};
let foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
foo = new Proxy(foo, callStackTracker(['foo']));
console.log(foo.bar.star.guitar); // "geetar"
console.log(foo.bar.star.clarinet); // Error: Couldn't resolve: foo.bar.star.clarinet
console.log(foo.bar.boat); // Error: Couldn't resolve: foo.bar.boat
I am then throwing this resolved path as an error in this example, but you could do whatever you like with it.
this would work, but I want to log the full path, not just the point where it failed. Proxy objects are cool tho.
– Alexander Mills
Nov 23 '18 at 9:44
Not sure I get you - it does give the full path
– Lauren
Nov 23 '18 at 11:08
You have 3 console.log output lines, they arent showing the full path, only shows where it failed. For example if it failed at bar it would say could not resolvefoo.bar
– Alexander Mills
Nov 23 '18 at 20:50
1
Ah yes I get you now! Hmm, needs more thought.
– Lauren
Nov 24 '18 at 0:48
Any new ideas on this front? thx. This answer is fine, just leave it.
– Alexander Mills
Nov 29 '18 at 21:17
add a comment |
If you are able to control the root variables that people can refer to, you could wrap them in a Proxy object which tracks the property access all the way down, like so:
function callStackTracker(propsSoFar) {
return {
get: function(obj, prop) {
if (prop in obj) {
return typeof obj[prop] === "object" ?
new Proxy(obj[prop], callStackTracker(propsSoFar.concat(prop))) :
obj[prop];
} else {
throw new Error("Couldn't resolve: " + propsSoFar.concat(prop).join('.'));
}
}
};
};
let foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
foo = new Proxy(foo, callStackTracker(['foo']));
console.log(foo.bar.star.guitar); // "geetar"
console.log(foo.bar.star.clarinet); // Error: Couldn't resolve: foo.bar.star.clarinet
console.log(foo.bar.boat); // Error: Couldn't resolve: foo.bar.boat
I am then throwing this resolved path as an error in this example, but you could do whatever you like with it.
this would work, but I want to log the full path, not just the point where it failed. Proxy objects are cool tho.
– Alexander Mills
Nov 23 '18 at 9:44
Not sure I get you - it does give the full path
– Lauren
Nov 23 '18 at 11:08
You have 3 console.log output lines, they arent showing the full path, only shows where it failed. For example if it failed at bar it would say could not resolvefoo.bar
– Alexander Mills
Nov 23 '18 at 20:50
1
Ah yes I get you now! Hmm, needs more thought.
– Lauren
Nov 24 '18 at 0:48
Any new ideas on this front? thx. This answer is fine, just leave it.
– Alexander Mills
Nov 29 '18 at 21:17
add a comment |
If you are able to control the root variables that people can refer to, you could wrap them in a Proxy object which tracks the property access all the way down, like so:
function callStackTracker(propsSoFar) {
return {
get: function(obj, prop) {
if (prop in obj) {
return typeof obj[prop] === "object" ?
new Proxy(obj[prop], callStackTracker(propsSoFar.concat(prop))) :
obj[prop];
} else {
throw new Error("Couldn't resolve: " + propsSoFar.concat(prop).join('.'));
}
}
};
};
let foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
foo = new Proxy(foo, callStackTracker(['foo']));
console.log(foo.bar.star.guitar); // "geetar"
console.log(foo.bar.star.clarinet); // Error: Couldn't resolve: foo.bar.star.clarinet
console.log(foo.bar.boat); // Error: Couldn't resolve: foo.bar.boat
I am then throwing this resolved path as an error in this example, but you could do whatever you like with it.
If you are able to control the root variables that people can refer to, you could wrap them in a Proxy object which tracks the property access all the way down, like so:
function callStackTracker(propsSoFar) {
return {
get: function(obj, prop) {
if (prop in obj) {
return typeof obj[prop] === "object" ?
new Proxy(obj[prop], callStackTracker(propsSoFar.concat(prop))) :
obj[prop];
} else {
throw new Error("Couldn't resolve: " + propsSoFar.concat(prop).join('.'));
}
}
};
};
let foo = {
bar: {
star: {
guitar: 'geetar'
}
}
}
foo = new Proxy(foo, callStackTracker(['foo']));
console.log(foo.bar.star.guitar); // "geetar"
console.log(foo.bar.star.clarinet); // Error: Couldn't resolve: foo.bar.star.clarinet
console.log(foo.bar.boat); // Error: Couldn't resolve: foo.bar.boat
I am then throwing this resolved path as an error in this example, but you could do whatever you like with it.
answered Nov 23 '18 at 7:49
LaurenLauren
1,2131129
1,2131129
this would work, but I want to log the full path, not just the point where it failed. Proxy objects are cool tho.
– Alexander Mills
Nov 23 '18 at 9:44
Not sure I get you - it does give the full path
– Lauren
Nov 23 '18 at 11:08
You have 3 console.log output lines, they arent showing the full path, only shows where it failed. For example if it failed at bar it would say could not resolvefoo.bar
– Alexander Mills
Nov 23 '18 at 20:50
1
Ah yes I get you now! Hmm, needs more thought.
– Lauren
Nov 24 '18 at 0:48
Any new ideas on this front? thx. This answer is fine, just leave it.
– Alexander Mills
Nov 29 '18 at 21:17
add a comment |
this would work, but I want to log the full path, not just the point where it failed. Proxy objects are cool tho.
– Alexander Mills
Nov 23 '18 at 9:44
Not sure I get you - it does give the full path
– Lauren
Nov 23 '18 at 11:08
You have 3 console.log output lines, they arent showing the full path, only shows where it failed. For example if it failed at bar it would say could not resolvefoo.bar
– Alexander Mills
Nov 23 '18 at 20:50
1
Ah yes I get you now! Hmm, needs more thought.
– Lauren
Nov 24 '18 at 0:48
Any new ideas on this front? thx. This answer is fine, just leave it.
– Alexander Mills
Nov 29 '18 at 21:17
this would work, but I want to log the full path, not just the point where it failed. Proxy objects are cool tho.
– Alexander Mills
Nov 23 '18 at 9:44
this would work, but I want to log the full path, not just the point where it failed. Proxy objects are cool tho.
– Alexander Mills
Nov 23 '18 at 9:44
Not sure I get you - it does give the full path
– Lauren
Nov 23 '18 at 11:08
Not sure I get you - it does give the full path
– Lauren
Nov 23 '18 at 11:08
You have 3 console.log output lines, they arent showing the full path, only shows where it failed. For example if it failed at bar it would say could not resolve
foo.bar
– Alexander Mills
Nov 23 '18 at 20:50
You have 3 console.log output lines, they arent showing the full path, only shows where it failed. For example if it failed at bar it would say could not resolve
foo.bar
– Alexander Mills
Nov 23 '18 at 20:50
1
1
Ah yes I get you now! Hmm, needs more thought.
– Lauren
Nov 24 '18 at 0:48
Ah yes I get you now! Hmm, needs more thought.
– Lauren
Nov 24 '18 at 0:48
Any new ideas on this front? thx. This answer is fine, just leave it.
– Alexander Mills
Nov 29 '18 at 21:17
Any new ideas on this front? thx. This answer is fine, just leave it.
– Alexander Mills
Nov 29 '18 at 21:17
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53439136%2fget-string-representation-of-object-path%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown