Skip to content

Instantly share code, notes, and snippets.

@mshick
Last active December 16, 2021 07:15
Show Gist options
  • Save mshick/64ed06ec26b98fb56201b32c1a432291 to your computer and use it in GitHub Desktop.
Save mshick/64ed06ec26b98fb56201b32c1a432291 to your computer and use it in GitHub Desktop.
tasneem

Desired

{
  "test_logoCollection": {
    "items": [
      {
        "globalRef": {
          "id": "Header",
          "key": "Btl6om8lm9ojt0M0jcbRW"
        },
        "showBorder": false,
        "components": {
          "items": []
        },
        "image": {
          "url": "https://greatwall-sandbox-sandbox-image.imgix.net/1386588286/xpm/logo.png?auto=compress",
          "altText": null
        }
      }
    ]
  }
}

Original

{
  "results": {
    "ops": [
      { "path": "items[0]", "mapping": "$finalResolver[0].params.logo[0]" },
      { "path": "items[1]", "mapping": "$finalResolver[1].params.logo[0]" },
      { "path": "items[0].globalRef", "mapping": "$finalResolver[0]" },
      { "path": "items[1].globalRef", "mapping": "$finalResolver[1]" }
    ]
  }
}

Solution

Explanation

  1. We set items to the results of the JSONPath / mapping statement. Assuming every item in the $finalResolver array has a logo[0] then this will be the same length as the $finalResolver array, and items will have hoisted the logo[0] object up to the top.

  2. We iterate this new items array, which should be the same length as the $finalResolver array. Using an expression, we are able to get (lodash.fp.get) the full value of the $finalResolver root object, and set it under the globalRef property. Note that you will have duplicated data in your return objects, since $finalResolver is necessarily inclusive of .params.logo[0]. That said, you could remove that duplicated data using the op remove in a later step in the ops.

{
  "results": {
    "ops": [
      {
        "path": "items",
        "mapping": "$finalResolver[*].params.logo[0]"
      },
      {
        "path": "items[*].globalRef",
        "mapping": [
          ["expressionEval", { "expression": "get($loop.key, $finalResolver)" }]
        ]
      }
    ]
  }
}

Explicit mapping solution

{
  "results": {
    "ops": [
      {
        "path": "items",
        "mapping": "$finalResolver[*]"
      },
      {
        "path": "items[*]",
        "mapping": "$finalResolver[*].params.logo[0]"
      },
      {
        "path": "items[*].globalRef",
        "mapping": "$loop.item"
      },
      {
        "path": "items[*].id",
        "op": "remove"
      },
      {
        "path": "items[*].key",
        "op": "remove"
      },
      {
        "path": "items[*].params",
        "op": "remove"
      }
    ]
  }
}
@TasneemZh
Copy link

TasneemZh commented Dec 16, 2021

Thank you so much for your time and efforts! What you wrote describes precisely the issue I'm having and the solution I want to reach. The approach is indeed easy to understand and seems logical but it returned three null objects:

    "test_logo": {
       "items": [
         {
           "globalRef": null,
           "showBorder": null,
           "components": null,
           "image": null
         },
         {
           "globalRef": null,
           "showBorder": null,
           "components": null,
           "image": null
         },
         {
           "globalRef": null,
           "showBorder": null,
           "components": null,
           "image": null
         }
       ]
     }

The query:

 query {
   test_logo(url: "/globalElements") {
     items {
       globalRef {
         id
         key
       }
       showBorder
       components {
         items {
           id
           key
         }
       }
       image {
         url
         altText
       }
     }
   }
 }

But it only needed a simple change to return the results:

{
"path": "items",
"mapping": "$finalResolver[*].params.logo[0]"
}

     "test_logo": {
       "items": [
         {
           "globalRef": {
             "id": null,
             "key": null
           },
           "showBorder": false,
           "components": {
             "items": null
           },
           "image": {
             "url": "https://greatwall-sandbox-sandbox-image.imgix.net/1386588286/xpm/logo.png?auto=compress",
             "altText": ""
           }
         }
       ]
     }

However, globalRef mapping doesn't seem to work. I have tried to use the source $finalResolver instead of $loop.item but the result were still null. Just when I use a specific index it returns the globalRef of that element value, or when I use the previous mapping approach for globalRef (but it returns the elements in order, not the correct reference)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment