Get content relationship fields from a slice

Hello,

I'm trying to get the data from my content relationship field which is in the non repeatable part of my slice. I am managing to get the object, but not retrieve data from it. I know I should use fetch links or graphql and I've looked at the docs but I can't understand (i'm quite new to nextjs & graphql).

I'm also trying to fetch the data from the getStaticProps but it returns undefined...

With this code :

const HomeLayout1 = ({ slice }) => {

 if (prismicH.isFilled.contentRelationship(slice.primary.project)) {
     const projectslug = slice.primary.project.uid;
     const client = createClient();
     const project_ = client.getByUID("project", projectslug);
     console.log(project_);
 }

return (

I get
Screenshot 2023-05-31 at 11.21.06

but how do I access this? I've tried using

const project_name = project_.primary.project_name;
or
const project_name = project_.data.project_name;

But it returns undefined.

I've tried to put something like

{project_.data.project_name}

inside of the return, but no luck either...

Hello @ondine

Thanks for reaching out to us.

You need to use GraphQuery to retrieve linked documents from Slice. Looking at first glance, I found out that you are getting Undefined error on retrieving primary-level data. I believe this doesn't come under slice:
const project_name = project_.primary.project_name;
Can you provide me with minimal reproduction to debug the issue? Could you share the URL of your repository with me? You can send it via DM if you prefer.

Thanks,
Priyanka

Hello Priyanka,

I'm sending you the repo via DM!

This is my index (where there is my slices)

import { SliceZone} from '@prismicio/react'
import { createClient } from '@/prismicio'
import { components } from '@/slices'

import Head from "next/head";
import { Layout } from "../components/Layout";



export default function Page({ page })  {

return (
  <Layout>
    <Head>
      <title>{page.data.title}</title>
    </Head> 
    <main className='home-container'>
    <SliceZone slices={page.data.slices} components={components} />
    </main>
    </Layout> 
); 

} 

export async function getStaticProps({ previewData }) {
  const client = createClient ({previewData})
  const page = await client.getSingle('homepage');

  return {
    props: {
      page
    } 
  }
} 

The one slice where there is the content relationship field I want to retrieve:

{
  "id": "home_one_image",
  "type": "SharedSlice",
  "name": "Home1Image",
  "description": "Home1Image",
  "variations": [
    {
      "id": "default",
      "name": "Default",
      "docURL": "...",
      "version": "initial",
      "description": "Default",
      "imageUrl": "",
      "primary": {
        "project": {
          "type": "Link",
          "config": { "label": "Project", "select": "document" }
        },
        "short_description": {
          "type": "StructuredText",
          "config": {
            "label": "Short description",
            "placeholder": "",
            "allowTargetBlank": true,
            "single": "paragraph,preformatted,heading1,heading2,heading3,heading4,heading5,heading6,strong,em,hyperlink,image,embed,list-item,o-list-item,rtl"
          }
        },
        "image_1": {
          "type": "Image",
          "config": { "label": "Image 1", "constraint": {}, "thumbnails": [] }
        }
      },
      "items": {}
    },
    {
      "id": "withOneVideo",
      "name": "with One video",
      "docURL": "...",
      "version": "initial",
      "description": "Default",
      "imageUrl": "",
      "primary": {
        "project": {
          "type": "Link",
          "config": { "label": "Project", "select": "document" }
        },
        "short_description": {
          "type": "StructuredText",
          "config": {
            "label": "Short description",
            "placeholder": "",
            "allowTargetBlank": true,
            "single": "paragraph,preformatted,heading1,heading2,heading3,heading4,heading5,heading6,strong,em,hyperlink,image,embed,list-item,o-list-item,rtl"
          }
        },
        "video_id": {
          "type": "Text",
          "config": { "label": "Video ID", "placeholder": "" }
        }
      },
      "items": {}
    }
  ]
}

and this is the index.js from the slice :

import * as prismicH from "@prismicio/helpers";
import { PrismicNextImage } from "@prismicio/next";
import { createClient } from '@/prismicio'
import { GraphQLClient, gql } from "graphql-request";
import { PrismicLink, PrismicText, SliceZone } from "@prismicio/react";

import { PrismicRichText } from "@prismicio/react"

 

/**
 * @typedef {import("@prismicio/client").Content.Home1ImageSlice} Home1ImageSlice
 * @typedef {import("@prismicio/react").SliceComponentProps<Home1ImageSlice>} Home1ImageProps
 * @param {Home1ImageProps}
 */
const Home1Image = ({ slice }) => {

  const image1 = slice.primary.image_1;
  const sliceVariation = slice.variation;
  

  const projectslug = slice.primary.project.uid;
  const client = createClient();
  const project_ = client.getByUID("project", projectslug);
/// this works & returns a promise pending like in screenshot
  console.log(project_);
/// this works
  console.log(projectslug);
/// this returns the error "TypeError: Cannot read properties of undefined (reading 'project_name')"
  console.log(project_.data.project_name)

  return (
    <section 
      className={`home-layout home-layout-1 ${sliceVariation}`}
      data-slice-type={slice.slice_type}
      data-slice-variation={slice.variation}
    >
       <div className="project-title">
            (variation: {slice.variation}) <br></br>

             {projectslug} (the project slug is showing)

            <PrismicRichText field={slice.primary.short_description} />
        </div>

        <div className="images-container">

        {slice.variation === 'withOneVideo' ? (
            <video autoPlay muted playsInline poster="http://localhost:3000/videcover.jpg">
            <source src="https://player.vimeo.com/video/${slice.primary.video_id}" type="video/mp4" />
            Your browser does not support the video tag.
            </video>
          ) : (
            <>
              {prismicH.isFilled.image(image1) && (
                <div className="image-container">
                  <PrismicNextImage
                    field={image1}
                    className="object-cover"
                    alt=""
                  />
                </div>
              )}
            </>
          )}

           

        </div>

     
    </section>
  );
};

export default Home1Image;


and inside my repeatable project type, I have a field called "project_name" (data.project_name).
Screenshot 2023-05-31 at 17.59.33

I need to display the project name and get the url to link to the project.

Let me know if that's sufficient!

Hello @ondine

I have checked your repo and found that project_name is a Key Text field, and ithis field is not under the Slice. It's a top-level field.
So your code for templating this should look like this:

{document.data.project_name}

And to retrieve the Content relationship field from Slice Machine Slice's is, please follow this guide: GraphQuery - Documentation - Prismic

It should look like this:

graphQuery={
  homepage {
    slices {
      ...on home_one_image {
        variation {
          ...on default {
            primary {
              project {
                ...on project {
                            project_ name
                }
              }
            }
          }
        }
      }
    }
  }
}

Give this a try, and let me know.

Thanks,
Priyanka