简体   繁体   中英

Formating JSON data from firestore

I am using a cloud function to download my db collection as a JSON file.

The code is

exports.csvJsonReport = functions.https.onRequest((request, response) => {
  const db = admin.firestore()
  const userAnswers = db.collection('/surveys/CNA/submissions')
  return (
    userAnswers
      .get()
      .then(querySnapshot => {
        let answers = []
        querySnapshot.forEach(doc => {
          const answer = doc.data()
          answers.push({ ...answer.answers, ...answer.anonUser })
        })

        response.setHeader('Content-disposition', 'attachment; filename=cna.json')
        response.set('Content-Type', 'application/json')
        response.status(200).send(answers)
      })
      .catch(error => {
        console.log(error)
      })
  )
})

Most of the time I only care about value , but sometimes value is nested inside..and when it is nested, I will need value and name

current output

[{
"2": {
      "loopIndex": null,
      "questionType": "multiChoice",
      "value": "Farm owner",
      "id": 1
    },
"7": {
      "1": {
        "name": "Enviroment management",
        "questionType": "responsiveMultiCheckBox",
        "valueId": 4,
        "value": "My top priority right now",
        "id": 1
      },
      "2": {
        "questionType": "responsiveMultiCheckBox",
        "valueId": 3,
        "value": "One of my top priorities",
        "id": 2,
        "name": "Financial management"
      },
      "3": {
        "value": "My top priority right now",
        "id": 3,
        "name": "People management",
        "questionType": "responsiveMultiCheckBox",
        "valueId": 4
      },
      "4": {
        "name": "Reproduction management",
        "questionType": "responsiveMultiCheckBox",
        "valueId": 4,
        "value": "My top priority right now",
        "id": 4
      },
      "5": {
        "name": "Feed management",
        "questionType": "responsiveMultiCheckBox",
        "valueId": 4,
        "value": "My top priority right now",
        "id": 5
      }
    },
}]

desired output:

[{
    "2": {
          "value": "Farm owner",
        },
    "7": {
          "1": {
            "name": "Enviroment management",
            "value": "My top priority right now",
          },
          "2": {
            "value": "One of my top priorities",
            "name": "Financial management"
          },
          "3": {
            "value": "My top priority right now",
            "name": "People management",
          },
          "4": {
            "name": "Reproduction management",
            "value": "My top priority right now",
         },
          "5": {
            "name": "Feed management",
            "value": "My top priority right now",
          }
        },
    }]

I have tried

answer.answers.map(questionId => {
            return console.log('value', questionId.value)
          })

but answers.answers.map is not a function

here is a working fiddle: https://jsfiddle.net/uekbhta6/2/

let result = {}; 
// I am assuming that your answers array always contains one object with the rest of data    
for (let id in answers[0])
{
    // If the value is present on the 1st level, push it to the buffer
    if (answers[0][id].value) 
    {
        result[id] = answers[0][id].value;
    }
    // otherwise, iterate through the second level and push name/value to result buffer
    else
    {
       result[id] = {};
       for(let id2 in answers[0][id])
       {
          result[id][id2] = {
                name:answers[0][id][id2].name,
              value:answers[0][id][id2].value
          };
       }
    }   
}
// wrap result in an array and print
console.log([result])

It could be done more elegantly with Array.reduce() , however it is getting late and I need some sleep.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM