GraphQL nodes and edges and nested data

I've been poking around the forum, Jobber's docs, and GraphQL docs (really weird concepts for me currently), but can't wrap my head around how to break down this nested data.

I was using edges and then nodes, now I think I'm simplifying it by just using nodes.

I want to get a list of all quotes from Jobber, including the custom fields associated with those quotes.

I'm keeping the query as simple as possible to start with, but may need to flesh it out with other details in the future.

The test query is:

query JobberQuotesQuery {
  quotes (searchTerm: "Hands", first: 1) {
    nodes {
      id
      quoteNumber
      quoteStatus
      amounts{
        total
        subtotal
        taxAmount
        nonTaxAmount
        discountAmount
      }
      customFields {
        ... on CustomFieldText {
          id
          label
          valueText
        }
      }
    }
  }
}

And the result is:

{
  "data": {
    "quotes": {
      "nodes": [
        {
          "id": "Z2lkOi8vSm9iYmVyL1F1b3RlLzE5ODYzMzUz",
          "quoteNumber": "41379",
          "quoteStatus": "archived",
          "amounts": {
            "total": 0.98,
            "subtotal": 0.87,
            "taxAmount": 0.11,
            "nonTaxAmount": 0,
            "discountAmount": 0
          },
          "customFields": [
            {
              "id": "MTk4NjMzNTM6OjE0NTgwNTE=",
              "label": "Site Name",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjEyNzQ4OTA=",
              "label": "BILL TO",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExMzYxNDY=",
              "label": "PO#",
              "valueText": "-"
            },
            {
              "id": "MTk4NjMzNTM6OjExMzYxNTM=",
              "label": "WO#",
              "valueText": "-"
            },
            {
              "id": "MTk4NjMzNTM6OjExMzkxNDk=",
              "label": "SalesRep",
              "valueText": "Dv"
            },
            {},
            {
              "id": "MTk4NjMzNTM6OjExMzYxNTY=",
              "label": "IVR",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExNDAyNzU=",
              "label": "On-Site Contact Name",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExNDAyNzk=",
              "label": "On-Site Contact Phone",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExNDAyODM=",
              "label": "On-Site Contact Email",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExNDAyODc=",
              "label": "Company A/P Email",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExNjM1MTE=",
              "label": "Property A/P Email",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExNjM1MTU=",
              "label": "Property A/P Name",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExODQzMTA=",
              "label": "Client Notes",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExODQzMTQ=",
              "label": "Property Work Notes",
              "valueText": ""
            },
            {
              "id": "MTk4NjMzNTM6OjExNTEwMTA=",
              "label": "CompanyCam Project",
              "valueText": ""
            }
          ]
        }
      ]
    }
  }
}

I'm not quite getting how I can breakout the various "customFields" so they can be displayed and sorted/filtered by. Especially as they are subject to change in the future, so hardcoding them in the query is not desirable.

I've reviewed other suggestions for using a transformer on the query, but I'm just not able to correlate it to my data layout.

Any assistance would be appreciated.

Thanks,

Dion

Hey @Addaline!

Do you know if you need the filtering/searching to happen on the backend or can it happen in the frontend? How many rows do you expect to have coming in from this data source?

Either way, unnesting this seems like a bit of a doozy. If you're looking to do it on the frontend, you might try something like this:

function unnestRow({amounts, customFields, ...remainingFields}){
  const customFieldData = formatDataAsObject(customFields);
  const customFieldsObject = _.zipObject(customFieldData.label, customFieldData.valueText);
  
  return {...remainingFields, ...amounts, ...customFieldsObject};
}

Here are some docs on formatDataAsObject and _.zipObject respectfully! Let me know if that helps or raises additional questions.

(More docs here and here that might help as well).