You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While object projections are useful, they are not easily done with deeply nested objects. You usually are forced into one of the three camps:
The uber-query. You build conditional projections for every single type at every possible injection point. This usually results in a massive query that is near impossible to maintain, if it is at all possible to cover every point. Or you just give up after a certain level of nesting which may be very problematic in front ends.
Post processing. You accept the limitations of groq and instead build an object traversal function that typically involves dereferencing those deeply nested references, which requires N+1 requests depending on how many times your references involve references. You also write transform functions to make things like @sanity/color-input's color type a simple rgba(r,g,b,a) string instead of all the values you aren't going to use.
Do none of the above. You write out code to handle large responses and ignore meta data you don't care about because it's tedious. It's not great, you could be working with more concise data structures, but it's not worth your development time.
I propose a new pipe function to transform arbitrarily nested objects: transform(selector:string|string[], ...conditionals:conditional[])
An example query:
*[_type == "post"]
| transform(
// A path or an array of paths to select objects from. In this case, anywhere
"**",
// Each part executed in waterfall manner so we can, e.g. deference all refs 3 levels deep before applying additional transforms
_type == "reference" => deref(3),
// Use this as a way of replacing objects with things like strings to be easier consumed by frontends
_type == "color" => format('rgba(#{r},#{g},#{b},#{a})', rgb),
// And projections which before would have had to known exact paths
_type == "image" => { "url": asset->url, "id": asset._ref }
)
Each conditional should be executed in waterfall manner for all objects selected by selector(s) should be processed, in case a conditional returns an object that can be transformed by a later conditional.
format(pattern:string, value:object): If value is null, return null, otherwise, replace tokens (type: path) in pattern by navigating value with token. Whichever token format wanted (e.g. {path.subpath}, #{path.subpath}, ${path.subpath}) is up to you
The text was updated successfully, but these errors were encountered:
While object projections are useful, they are not easily done with deeply nested objects. You usually are forced into one of the three camps:
I propose a new pipe function to transform arbitrarily nested objects:
transform(selector:string|string[], ...conditionals:conditional[])
An example query:
Each conditional should be executed in waterfall manner for all objects selected by selector(s) should be processed, in case a conditional returns an object that can be transformed by a later conditional.
The above query should be equivalent to:
Note that I have also mentioned two potential functions as well in here that may have been mentioned before:
deref(level:number)
: Dereferences the current object up to the given level times. I like Auto dereferencing pipe function #21's thinking.format(pattern:string, value:object)
: If value is null, return null, otherwise, replace tokens (type: path) in pattern by navigating value with token. Whichever token format wanted (e.g.{path.subpath}
,#{path.subpath}
,${path.subpath}
) is up to youThe text was updated successfully, but these errors were encountered: