0

I have an API call that returns a JSON response object. The shape of the data is bit a confusing and I can't figure out the exact object to run .map() and .filter() on to get my desired result.

  .then(response => {
    console.log(response); //see below for shape of data
    var dataSourceInfo = response.data.included.filter(
      element => element.type === "DataSource"
    );
    var dataSourceName = dataSourceInfo.map(function(included) {
      return included["name"];
    });
    console.log(dataSourceName);

In the two arrays, I'm attempting to filter over response.data.included to find an element by type. Then map over the returned filter to create a new ordered array. In one of the included arrays there is an identifying type of DataSource, here's an example:

included: [
  {
    id: "2147483604",
    type: "DataSource",
    name: "Some DataSource"
  }, 

I'm logging the dataSourceName but the array only has the one of the expected names, and it's only from the first array, so it's like the map isn't reaching the second data.data. Any idea how I can get both names to appear in the filtered array?

Edit: correct response object is in the codesandbox

5
  • 1
    I am having a hard time understanding your problem Commented Dec 20, 2018 at 21:25
  • I can see that response is an array so response.data should throw an error. It should be response[0].data or response.forEach/map/filter() Commented Dec 20, 2018 at 21:25
  • What is the expected result ? Commented Dec 20, 2018 at 21:30
  • So there's a type element of DataSource in one of the included arrays in response[0] and response[1] so the filter map should return [ dataSourceName1, dataSourceName2] Commented Dec 20, 2018 at 21:37
  • 1
    There must be a mistake in the textual representation you added for the response object. You depict it as an array of one element (not two), and that element is an object in which you define the data property twice, so only one will survive (an object cannot have two properties with the same name). Commented Dec 20, 2018 at 22:40

1 Answer 1

1

If I understand you correctly, you want a flat list of names where type is "DataSource" given an input that looks like this:

const response = {
  data: [
    {
      data: {
        data: {
          included: [
            { type: 'DataSource', name: 'First' },
            { type: 'Blah', name: 'Second' },
            { type: 'DataSource', name: 'Third' }
          ]
        }
      }
    },
    {
      data: {
        data: {
          included: [
            { type: 'DataSource', name: 'Fourth' },
            { type: 'Blah', name: 'Fifth' },
            { type: 'DataSource', name: 'Sixth' }
          ]
        }
      }
    },
  ]
}

const result = response.data.flatMap(({data: {data: {included}}}) => 
  included.reduce((memo, {type, name}) => {
    if (type === 'DataSource') {
      memo.push(name)
    }
    return memo;
  }, [])
)

console.log(result)

I've omitted parts of the response that aren't relative to the problem

Update:

Here's the code adjusted to work with the responseObject listed in https://codesandbox.io/s/ympo7pr0xx

const responseObject = [ { data: { data: { id: "2147483605", selfUri: "/schedules/2147483605", type: "Schedule", startTime: 1545409610826, status: "InProgress", query: { id: "2147483603", selfUri: "/queries/2147483603", type: "Query" }, dataSource: { id: "2147483604", selfUri: "/datasources/2147483604", type: "DataSource" } }, included: [ { id: "2147483603", selfUri: "/queries/2147483603", type: "Query", name: "Query1", status: "Scheduled", querySchema: { id: "2147483601", selfUri: "/queryschemas/2147483601", type: "QuerySchema" } }, { id: "2147483601", selfUri: "/dataschemas/2147483601", type: "DataSchema", name: "Phone Data" }, { id: "2147483601", selfUri: "/queryschemas/2147483601", type: "QuerySchema", name: "QS1", dataSchema: { id: "2147483601", selfUri: "/dataschemas/2147483601", type: "DataSchema" }, queriesUri: "/queryschemas/2147483601/queries" }, { id: "2147483604", selfUri: "/datasources/2147483604", type: "DataSource", name: "Standalone- 5K", description: "Standalone 5K record" } ] } }, { data: { data: { id: "2147483606", selfUri: "/schedules/2147483606", type: "Schedule", startTime: 1545410049652, status: "Pending", query: { id: "2147483603", selfUri: "/queries/2147483603", type: "Query" }, dataSource: { id: "2147483608", selfUri: "/datasources/2147483608", type: "DataSource" } }, included: [ { id: "2147483608", selfUri: "/datasources/2147483608", type: "DataSource", name: "Standalone 5", description: "Standalone 5 record" }, { id: "2147483603", selfUri: "/queries/2147483603", type: "Query", name: "Query1", status: "Scheduled", querySchema: { id: "2147483601", selfUri: "/queryschemas/2147483601", type: "QuerySchema" }, schedulesUri: "/queries/2147483603/schedules" }, { id: "2147483601", selfUri: "/dataschemas/2147483601", type: "DataSchema", name: "Phone Data" }, { id: "2147483601", selfUri: "/queryschemas/2147483601", type: "QuerySchema", name: "QS1", dataSchema: { id: "2147483601", selfUri: "/dataschemas/2147483601", type: "DataSchema" } } ] } } ];

const result = responseObject.flatMap(({data: {included}}) => 
  included.reduce((memo, {type, name}) => {
    if (type === 'DataSource') {
      memo.push(name)
    }
    return memo;
  }, [])
)

console.log(result)

Sign up to request clarification or add additional context in comments.

21 Comments

I've updated my initial post, maybe this will give you a more clear understanding. I left out the irrelevant included arrays. So using map and filter I should be getting back [Standalone 5K, Records 5K]. It is currently only returning the first name [Standalone 5K]
ok, it looks like the only difference was an extra nested data - updated
actually, I rolled back the changes - doesn't my code do what you want?
the example responseObject you posted doesn't look right, it has this shape: [{ data: { ... }, data: { ... } }], i.e. there's an object with two data keys - the second data will overwrite the first
@DJ2 The shape of responseObject given in the post is incorrect. Read the previous comments
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.