Home > Enterprise >  Typescript - how do you get specific values on Object.entries() on nested, complicated objects that
Typescript - how do you get specific values on Object.entries() on nested, complicated objects that

Time:06-14

I'm having a hard time understanding objects and the Object.entries() method on complicated objects that come from third parties, specifically, DataDog.

I want a specific metric and I'm not sure how to get to it. I marked it "data_I_want" with a value of "HERE".

Based on what I understand from this API, that function returns an object. An example of the structure looks like this:

{
  "data": [
    "attributes": {
        "attributes": {
            "view": {
                "data_I_want": "HERE"
            }
        }
    }
  ],
  "links": {
        "next": "stuff"
    },
    "meta": {
        "page": {
            "after": "stuff"
        }
    }
}

The code that gets it is this

RUMApiInstance
  .searchRUMEvents(RUMApiParams)
  .then((data: v2.RUMEventsResponse) => {

    let ddDataViews = data;

    // where I'm stuck/confused
    Object.entries(ddDataViews).forEach(([key, value]) =>
      console.log('values: '   `${key}: ${value}`)
    );
    
  })
  .catch((error: any) => console.error(error));

How can I access and process nested objects, arrays or JSON?

So there's a really long answer but the first thing I tried was basically this, from the answer:

You can access it this way

data.items[1].name

or

data["items"][1]["name"]

Both ways are equal.

When I try this in my context:

let ddDataViews = data.attributes[0].attributes.view.data_I_want;

I get an error from VS Code in typescript:

Property 'attributes' does not exist on type 'RUMEventsResponse'.ts(2339)

Why?

I do notice in the linked answer, that the object is a variable and mine is not? Do you have to like, declare it as a variable for that method to work?

So I move on to try to use the Object.entries() method

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

The Object.entries() method returns an array of a given object's own enumerable string-keyed property [key, value] pairs. This is the same as iterating with a for...in loop, except that a for...in loop enumerates properties in the prototype chain as well.

So this seems like it's the right direction.

So my logic is as follows:

  1. get the entries of the object
  2. if its data, then loop over that object
  3. inside that object, loop over that object

So this is what I thought up:

Object.entries(ddDataViews).forEach(([key, value]) =>
      if (key == data) {
        console.log('values: '   `${value}`)
      }
    );

However, this code doesn't work I get:

'{' expected.ts(1005)

I'm beyond confused as to how objects work in typescript with third party APIs, how do I get "data_I_want" with typescript/Object.entries() from an API?

CodePudding user response:

Based on the example above, you should be able to access data_I_want by using:

data.data[0].attributes.attributes.view.data_I_want

You mention in a comment

I go typeof data.data and it says object but isn't [] the syntax for an array...? so which is it? Like an array of objects? SO JS says it's an object?

It should say object :) Reference: https://www.w3schools.com/js/js_typeof.asp

CodePudding user response:

I have a knack for getting extremely overwhelmed and anxious when I can't immediately figure something out so I panic and shut down...not something this board can help me with but I digress...I'm writing this out as a journal entry if you will.

In this context - when I did data this is what it represented:

{}

With all the content inside of it. The type of data here is an "object" - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#examples

When I went:

data.attributes[0].attributes.view.data_I_want;

It was undefined because well...there was nothing because when I do just data I get:

{}

There is no "attributes" anywhere...

So I need to do a level deeper and say:

data.data

Which gives me the value of data:

"data": [
    "attributes": {
        "attributes": {
            "view": {
                "data_I_want": "HERE"
            }
        }
    },
    "attributes": {
        "attributes": {
            "view": {
                "data_I_want": "HERE"
            }
        }
    },
    "attributes": {
        "attributes": {
            "view": {
                "data_I_want": "HERE"
            }
        }
    },
  ],
...

Data is an array. An array of objects, inside of...an object - so when I asked for the typeof, it represented the entire object.

From here, once you know that data is an array, you access the one you want with brackets and a number like [0]

  • Related