In Sanity Studio, I was trying to get all Document's properties inside an input Component. Follow this article An officially supported way to get at the document content I was able to use withDocument HOC to get Document data, but some of them have the type of "reference" thus I can only get _ref and _type instead of the entire object. How can I make it?
4 Answers
You can dereference the values with the dereferencing operator ->. So, let's say you have a document called book with a property authors that is an array of reference types.
You could get the values for the authors array this way:
const books = await client.fetch(
`*[_type == "book"] {
...,
authors[]->
}`
)
You can check Sanity's docs on GROQ queries for more and better information.
I've figured it out by using Sanity Client.
Import the client in your component:
import client from 'part:@sanity/base/client';
Start to query using _ref as the _id in your GROQ query
...
componentDidMount = () => {
client.fetch(`*[_type == "template" && _id == "<put _ref value here>"]{
title,
body
}`).then(response => {
console.info('RESPONSE', response);
})
}
So encountered similar issue, here is how I solved it.
First: to fetch all document: lets, call the document, product.
client.fetch(`*[_type == "product"]`)
Second: to get specific property from each products In sanity, there is something called projections, it's used to return specific property from object.
Let's say our each item in our products array of objects has property of name, category, price, etc
products=[
{
id:""
name:"",
price:"",
productCategory:"",
},
{
id:""
name:"",
price:"",
productCategory:"",
},
]
Thus, to return only name and price of each products from our query, we would write:
client.fetch(`*[_type == "product"]{name, price}`)
where {} marks the projection.
However, our productCategory field is a type reference in our product schema, such that:
{
name: "productCategory ",
title: "productCategory ",
type: "reference",
to: [{ type: "category" }],
},
category being another document with its own schema, category.js
Third: The fetch query in First above would return array of product objects, with the productCategory in the form of
{type: "ref", ref:"random numbers"}
What we want to do is get the name of that category being referenced by the ref
:
So we would add the productCategory to our projection
client.fetch(`*[_type == "product"]{name, price,productCategory }`)
Fourth: Now we direct the ref to its original document, and access the property corresponding to that ref number:
client.fetch(`*[_type == "product"]{name, price,productCategory-> }`)
This would return the object for that document as it's in the category.js schema:
{
id:"",
name:"HeadPhones",
type:"string",
}
Sixth: To get the name as we can either do:
client.fetch(`*[_type == "product"]{name, price,productCategory->{name} }`)
which will return
{
name:"",
price:""
productCategory:{name:"HeadPhone"}
}
or do
client.fetch(`*[_type == "product"]{name, price, "category": productCategory->name }`)
{
name:"",
price:""
category:"HeadPhones"
}
We've finally mapped the ref
to the corresponding document and extracted the name.
Source from Sanity https://www.sanity.io/docs/how-queries-work
An interesting approach is to make another query based on references from the parent document:
*[_type == "page"] {
"breadcrumbs": *[_type == "page" && _id in ^.breadcrumbs[]._ref] {
seo_title,
"slug": slug.current,
}
}
Result:
"breadcrumbs": [
{
"seo_title": "Company",
"slug": "company"
},
{
"seo_title": "Home",
"slug": "home"
}
]
In this example, we consult the seo_title
and the slug
of a page, checking whether its _id
is in the array with references to the 'bradcrumbs' property that is in the parent document.
Another informations on Sanity documentation: https://www.sanity.io/docs/how-queries-work#52023b22ca05.