GraphQL query differences in sandbox/next app

Enonic version: 7.8
OS: MacOS

Hey!

I’m trying to fetch a pictures absolute url from the cms via graphQL from the next.xp app by its content id.
The query that I’m trying to use works correctly when invoked in the Playground


{
  guillotine {
    get(
      key: "c4b38a24-7857-4a56-bf92-a6bc17369a15") {
    displayName
              ... on media_Image { 
                mediaUrl(
                  type: absolute	
                )
              }
    }
  }
}

But goes to error with

Error: Error serializing `.common` returned from `getServerSideProps` in "/[[...contentPath]]".
Reason: `object` ("[object Error]") cannot be serialized as JSON. Please only return JSON serializable data types.

When invoked from the next app as follows:
Part.tsx:

query($path:ID!){
              guillotine {
                get(key:"c4b38a24-7857-4a56-bf92-a6bc17369a15") {
                  displayName
                  ... on media_Image { 
                    mediaUrl(
                      type: absolute	
                    )
                  }
                }
              }
            };

Additionally, the first query mentioned in the starters documentation Getting to know the API - Enonic Developer Portal produces a different result as well when invoked from the next app versus from the Playground.

I wasn’t able to figure out the difference what the execution context causes, can you point me to the right documents for that?

Hi @kpeter !

Let’s try to fix your issues.

One thing I see wrong immediately in your second query is that you define $path: ID! variable, but do not use it in your query, that will lead to unused variable graphql error.
To fix that try modifying your query to:

query($path:ID!){
              guillotine {
                get(key: $path) {     <=== notice the usage of $path instead of hard-coded id
                  displayName
                  ... on media_Image { 
                    mediaUrl(
                      type: absolute	
                    )
                  }
                }
              }
            };

$path variable will be automatically supplied by nextjs so you don’t need to worry about it.

What concerns the first query on the dev portal, you’re absolutely right – we forgot to update the reference after changing the app id from com.example.myproject to com.enonic.app.nextjsdemo

So to make it work you need to change it to:

{
    guillotine {
        query(query: "valid='true' and type='com.enonic.app.nextjsdemo:movie'", sort: "displayName") {
            id: _id
            displayName
        }
    }
}

Thanks for pointing that out we will update the doc !

Hey @pmi!

Thanks for replying! You were right of course about the unused param, now I’m seeming the same result as I do with the example query from the docs.

Basically my goal here is instead of using the $path variable, I’m trying to fetch an asset by its content id.

So again the query I’m trying to make work in the app is the following (I will change this later on to use a variable instead of the static string of course)

{
  guillotine {
    get(
      key: "c4b38a24-7857-4a56-bf92-a6bc17369a15") {
    displayName
      ... on media_Image { 
        mediaUrl(
          type: absolute	
        )
      }
    }
  }
}

As I mentioned it provides an expected answer when invoked from the guillotine playground as:

{
  "data": {
    "guillotine": {
      "get": {
        "displayName": "Brad Pitt",
        "mediaUrl": "http://localhost:8080/site/hmdb/draft/hmdb/_graphql/_/attachment/inline/c4b38a24-7857-4a56-bf92-a6bc17369a15:0e590e73e33d2575b7b1baed4d47a0111235c8bc/brad-pitt.jpg"
      }
    }
  }
}

However, invoking it from the application doesn’t populate the prop objects data field.

When I mentioned the example query producing different results, I meant the same behaviour.
During execution from the guillotine playground, I’m getting back the expected result.


  "data": {
    "guillotine": {
      "query": [
        {
          "id": "b909b9d6-0c45-447f-be67-6c2624a1dd31",
          "displayName": "No time to die"
        },
        {
          "id": "d140bba7-0fa1-44c0-b777-ac6330becaff",
          "displayName": "Pulp Fiction"
        },
        { ..etc

But similarly with the other query, after executing it within the app, the data field with the prop object remains empty.

Hi.

It would perhaps be helpful if you shared a bit more about your code, not just the graphql Query, but the whole component + component registration code.

Ok, it seems that I will need more data indeed to test it.

Also, I might’ve given you not the most accurate answer on the query from the docs.

My answer is correct for the case when you cloned nextjs app from the git repo manually.

But docs suggest installing it with enonic cli and app id in that case will be updated by the cli to com.enonic.myproject (unless you opt for something different) and the query from the docs should work fine.

Sure thing.

On the cms side, a new part with its corresponding js and xml files.
JS is just passing the rendering over to next, as all the rest as specified in the starter

var proxy = require('/lib/nextjs-proxy/proxy');
exports.get = proxy.get;

In the xml, i’ve created a few input fields out which the most interesting for the problem is the image.

  <input name="authorsImage" type="ImageSelector">
            <label>Authors Image</label>
            <occurrences minimum="0" maximum="1"/>
            <config>
                <allowPath>${site}/*</allowPath> 
                <treeMode>true</treeMode>
                <hideToggleIcon>true</hideToggleIcon>
            </config>
        </input>

I’m trying to resolve this image reference to an absolute url from next.xp app side, this is the core problem i’m looking for help with.

Next app side - I’m using the template repo https://github.com/enonic/nextjs-enonic-template where I have added a new part under …src/parts/pull-qoute

.tsx source

import React from "react";

import {PartProps} from "../../_enonicAdapter/views/BasePart";

export interface PullQuoteProp{
    bgColor: string,
    pullQuoteText: string,
    authorName: string,
    authorTitle: string,
    authorsImage:any,
}

const PullQuote = (props: PartProps) => {

    const pullQuoteData: PullQuoteProp = props.part.config;

    console.log(props); // based on the other examples I assume the props.data field should be the one populated with the results of the query(?) 

    return (


       <-- Custom web component invocation that would use the props, including the absolute image url --> 


    );

}

export default PullQuote;

export const getPicture =
     `{
  guillotine {
    get(
      key: "c4b38a24-7857-4a56-bf92-a6bc17369a15") { --> as mentioned I'd refactor this to use the pullQuoteData.authorsImage as a next step, if the rendering would work with hardcoded value first.
The authorsImage is correctly there as a content-key, that part is okay. 
    displayName
      ... on media_Image { 
        mediaUrl(
          type: absolute
        )
      }
    }
  }
}`;

In the _mappings.ts I’m registering the component as

ComponentRegistry.addPart(`${APP_NAME}:pull-quote`, {
    query: getPicture,
    view: PullQuote,
});

Everything else but the query works, the component renders correctly without trying to make the image work. That’s why I went with the assumption that the query must be incorrect.

Thanks for the info !

I will look into it tomorrow. Meanwhile try adding a query keyword around the outermost curly braces:

export const getPicture =
     `query {    <=== you did not have query here, just the curly brace
  guillotine {
    get(
      key: "c4b38a24-7857-4a56-bf92-a6bc17369a15") {
    displayName
      ... on media_Image { 
        mediaUrl(
          type: absolute
        )
      }
    }
  }
}`;
1 Like

Dang, that’s all it needed, of course something tiny like that.
Thanks for your patience working with me here.

2 Likes