1

Using Plotly.js in my React application, I wish to retrieve the "range" array from the layout object. This is what my code looks like:

 useEffect(() => {
        if (chartData) {
            
            console.log(chartData.layout.yaxis);
            console.log(chartData.layout.yaxis.range);

            console.log(JSON.stringify(chartData.layout.yaxis));
            
        }
    }, [chartData])

Output from console.log(chartData.layout.yaxis):

{
anchor: "x"
autorange: true
domain: (2) [0, 1]
range: (2) [-1611.7268768451163, 15422.563518243458]
title: {text: 'This is a sample text'}
type: "linear"
}

Output from console.log(chartData.layout.yaxis.range):

undefined

Output from console.log(JSON.stringify(chartData.layout.yaxis)):

{"anchor":"x","domain":[0,1],"title":{"text":"This is a sample text"}}

What I can't get my head around is the range is clearly present as an array in the first console.log but comes out as undefined with I try to access it directly in the second console.log.

What is the explanation behind this behavior and how do I retrieve the "range" array, that clearly is there?

Gustav Vingtoft
  • 355
  • 2
  • 16
  • For some `charData.layout.yaxis` , `range` is not present as you can see in your JSON.stringify example, you can use optional chaining to get values where they are present something like `charData.layout.yaxis?.range` – Navitas28 May 25 '23 at 13:02
  • 1
    Most likely the range property is being set asynchronously/after the log occurs ([example](https://jsfiddle.net/ohm7bp9s/1/), look at your browser console for results) - Here's an explanation: [Is Chrome’s JavaScript console lazy about evaluating objects?](https://stackoverflow.com/q/4057440) – Nick Parsons May 25 '23 at 13:02
  • @Navitas28 the output logs comes from the exact same object where "range" is present in the first console.log but when I try to access it at the next line its undefined, so I don't believe that's the case. – Gustav Vingtoft May 25 '23 at 13:07
  • @NickParsons If the "range" is present in the in the first console.log, how can it be async? – Gustav Vingtoft May 25 '23 at 13:07
  • 3
    @GustavVingtoft It's only present in the first log because you're logging a live reference to the object, so what you're seeing is not the object at the time it was logged, it's the object at the time you've "expanded" it within your dev-tools console. It's common for this type of thing to occur if you're setting the value of `range` asynchronously somehow (but not realising it) – Nick Parsons May 25 '23 at 13:12
  • range could be private property. – CodeThing May 25 '23 at 13:18
  • @NickParsons Gotcha and I believe you are right. When I add a setTImeout of 5 seconds I do indeed get the object. Do you have any knowledge on how I can wait for the range property to be set before accessing it? Again, working in React – Gustav Vingtoft May 25 '23 at 13:23
  • @GustavVingtoft I haven't used ploty before, but I imagine there should be a way. Are you setting the `range` value yourself manually (and if so, is that inside a callback of some type)? Also, are you working with [react-ploty](https://plotly.com/javascript/react/), if so, you should be able to tie your data/layout to state values and access the range value using those I would think. – Nick Parsons May 25 '23 at 13:30
  • 1
    @NickParsons Nope, the layout is coming from an API response. I'll try to find a solution, at least now I know why this situation occurred and learned something new about the dev-tools, so thank you for your help. Have a good day! – Gustav Vingtoft May 25 '23 at 13:32
  • 1
    You could listen for the `plotly_relayout` event in order to handle range (and other layout) updates. See https://plotly.com/javascript/plotlyjs-events/. – EricLavault May 25 '23 at 14:24

0 Answers0