Home > database >  Loop through array of differently structured JSON objects/arrays
Loop through array of differently structured JSON objects/arrays

Time:05-05

I feel like this is mostly an issue with how I'm looping through the JSON, so am posting that first. This is a series of JSON responses from Promise.allSettled() posted below.

The problem I am having is with the second "status" object between content and anoObject1 as I'm looping through the JSON responses. I've shown some console.logs() below that are successful

Here is the series of JSON responses:

[
    {
        "status": "fulfilled",
        "value": {
            "content": {
                "object1": {
                    "kv": "Y",
                    "kv1": "1000",
                    "kv2": {
                        "okv": "A",
                        "okv1": "1"
                    },
                    "kw": "A"
                }
            },
            "retrievalDate": "2022-05-04T23:01:57.710 0000"
        }
    },
    {
        "status": "fulfilled",
        "value": {
            "content": [
                {
                    "anoObject1": {
                        "ano": "A",
                        "ano1": {
                            "ona": "B",
                            "ona1": 11
                        },
                        "measureValue": "1.92",
                        "measureValue2": "N"
                    }
                },
                {
                    "anoObject2": {
                        "ano": "B",
                        "ano1": {
                            "ona": "Y",
                            "ona1": 11
                        },
                        "measureValue": "1.92",
                        "measureValue2": "N"
                    }
                }
            ],
            "retrievalDate": "2022-05-04T23:01:57.707 0000"
        }
    }
]

Here are the async fetch calls:

export async function allCallouts(key, value){

    const BASE_URL = 'https://baseurl.com/service/'
    const API_KEY = 'apikey'
    const endpoint1 = 'https://url1.com/a/';
    const endpoint2 = 'https://url1.com/b/';
    

    try{
        const results = await Promise.allSettled(
            [
                fetch(endpoint1).then((response) => response.json()),
                fetch(endpoint2).then((response) => response.json()),
            ]
        )
        return results
    } catch (error){
        console.log(error)
    }
}

Here is the function I am calling the first function from

async handleFetchCallouts() {

    returnedResults;

    await allCallouts(key, value)
        .then(results => {

            this.returnedResults = results

        }).catch(err => {
            console.log('this is err: '   err);
        })


    let arrayLength = this.returnedResults.length

    for (var i = 0; i < arrayLength; i  ) {

        //I am able to console.log(this.returnedResults[i].value.content)
        //it returns the response and number I am expecting
        //but the structure of the JSON response (above) is tripping me up
        

        if (this.returnedResults[i].value.content['object1'] != null) {

            //I can console.log() this successfully
            console.log(this.returnedResults[i].value.content['object1'].kv)

        }

        if (this.returnedResults[i].value.content['anoObject1'] != null) {

            //having trouble getting to this object and looping through each

        }

    }

}

Thank you for any help! If you see other design flaws with my code or an easier way to do things, please suggest.

CodePudding user response:

You can use Array.isArray() to ascertain if an object is an Array and customize how you handle the object accordingly.

// Same structure as in the question, but removed extraneous 
// fields and compacted for the sake of brevity.
const input = `[
    {"value":{"content":{"object1":{"kv":"Y"}}}},
    {"value":{"content":[
        {"anoObject1":{"ano":"A"}},
        {"anoObject1":{"ano":"B"}}
    ]}}]`;

const result = JSON.parse(input);
for (const r of result) {
  const content = r.value.content;
  if (Array.isArray(content)) {
    for (const c of content) {
      console.log(`anoObject1.ano = ${c.anoObject1.ano}`);
    }
  } else {
    console.log(`object1.kv = ${content.object1.kv}`);
  }
}

CodePudding user response:

For your second if statement in the for loop, you would have to iterate through all items under value.content. Replace the second if statement with this for a plug and play:

if (Array.isArray(this.returnedResults[i].value.content)) for (let i of this.returnedResults[i].value.content) {

}

Inside the new loop, i will be equivalent to

                {
                    "anoObject1": {
                        "ano": "A",
                        "ano1": {
                            "ona": "B",
                            "ona1": 11
                        },
                        "measureValue": "1.92",
                        "measureValue2": "N"
                    }
                }

The reason for this is that the second if statement was attempting to find a property/key of an array instead of each object in the array of objects.

I would also recommend reading up on the following to make your coding easier/better:

CodePudding user response:

Create a recursive function and dont use any hardcoded key. Iterate through the content and check if value is an array using Array.isArray. If so then handle it in a different function and so for if value is of type object

const arrayLength = [{
    "status": "fulfilled",
    "value": {
      "content": {
        "object1": {
          "kv": "Y",
          "kv1": "1000",
          "kv2": {
            "okv": "A",
            "okv1": "1"
          },
          "kw": "A"
        }
      },
      "retrievalDate": "2022-05-04T23:01:57.710 0000"
    }
  },
  {
    "status": "fulfilled",
    "value": {
      "content": [{
          "anoObject1": {
            "ano": "A",
            "ano1": {
              "ona": "B",
              "ona1": 11
            },
            "measureValue": "1.92",
            "measureValue2": "N"
          }
        },
        {
          "anoObject1": {
            "ano": "B",
            "ano1": {
              "ona": "Y",
              "ona1": 11
            },
            "measureValue": "1.92",
            "measureValue2": "N"
          }
        }
      ],
      "retrievalDate": "2022-05-04T23:01:57.707 0000"
    }
  }
]
for (let i = 0; i < arrayLength.length; i  ) {
  const content = arrayLength[i].value.content;
  // checking if value is of type array or object
  if (Array.isArray(content)) {
    handleContentArray(content)

  } else if (content && typeof(content) === 'object') {
    handleContentObject(content)
  }
}

function handleContentArray(contentArray) {
  // iterate the array
  contentArray.forEach(item => {
    // if the content of the array is an object then call the function which handles the object
    if (item && typeof item === 'object') {
      handleContentObject(item)
    }
  })
}

function handleContentObject(contentObject) {
  // iterate through the key
  for (let keys in contentObject) {
    // if the value of the key is an object then recursively call the same function
    if (contentObject && typeof(contentObject[keys]) === 'object') {
      return handleContentObject(contentObject[keys])
    } else {
      // log the key value pair
      console.log(`KEY:- ${keys}, VALUE: - ${contentObject[keys]}`)

    }
  }
}

  • Related