Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Object Id returning null #825

Closed
seagyn opened this issue Apr 25, 2019 · 11 comments
Closed

Object Id returning null #825

seagyn opened this issue Apr 25, 2019 · 11 comments
Assignees

Comments

@seagyn
Copy link

seagyn commented Apr 25, 2019

When performing a query on a custom post type, the {$post_type}Id of the node returns null. Normal posts work.

This returns the correct response:

query GetPosts {
  posts {
    edges {
      node {
      	postId
      }
    }
  }
}

This returns Cannot return null for non-nullable field Car.carId.:

query GetCars {
  cars {
    edges {
      node {
      	carId
      }
    }
  }
}

Running v0.3.2.

@paulgrieselhuber
Copy link
Contributor

@seagyn running in to the same thing. Are you returning a WPGraphQL type from this query by chance? Similar to:

'type' => \WPGraphQL\Types::post_object('post'),

or

'type' => \WPGraphQL\Types::list_of(\WPGraphQL\Types::post_object('post')),

In my app, I've been able to narrow this issue down to those sorts of queries, curious if it's the same on yours. Here is more detail.

@jasonbahl
Copy link
Collaborator

@seagyn @paulisloud can ya'll check with the latest develop branch? I merged a PR that I believe resolved this.

@jasonbahl
Copy link
Collaborator

If still having issues, it might come down to the Model Layer, and whether the entity is being restricted or not.

If your Custom Post Type or Custom Taxonomy is registered with specific capabilities, those capabilities are now being respected, which may be causing issues if you are querying for data that should not be publicly available.

@paulgrieselhuber
Copy link
Contributor

Still having this issue. Here is the schema for this post-type export, taken from CPT UI's export tool. I believe everything is as "public" as need be:

{
    "special": {
        "name": "special",
        "label": "Special",
        "singular_label": "Special",
        "description": "",
        "public": "true",
        "publicly_queryable": "true",
        "show_ui": "true",
        "show_in_nav_menus": "true",
        "show_in_rest": "true",
        "rest_base": "special",
        "rest_controller_class": "",
        "has_archive": "false",
        "has_archive_string": "",
        "exclude_from_search": "false",
        "capability_type": "post",
        "hierarchical": "false",
        "rewrite": "true",
        "rewrite_slug": "",
        "rewrite_withfront": "true",
        "query_var": "true",
        "query_var_slug": "",
        "menu_position": "",
        "show_in_menu": "true",
        "show_in_menu_string": "",
        "menu_icon": "https://www.website.com/wp-content/themes/theme/images/icon.svg",
        "supports": [
            "title",
            "thumbnail"
        ],
        "taxonomies": [],
        "labels": {
            "menu_name": "",
            "all_items": "",
            "add_new": "",
            "add_new_item": "",
            "edit_item": "",
            "new_item": "",
            "view_item": "",
            "view_items": "",
            "search_items": "",
            "not_found": "",
            "not_found_in_trash": "",
            "parent_item_colon": "",
            "featured_image": "",
            "set_featured_image": "",
            "remove_featured_image": "",
            "use_featured_image": "",
            "archives": "",
            "insert_into_item": "",
            "uploaded_to_this_item": "",
            "filter_items_list": "",
            "items_list_navigation": "",
            "items_list": "",
            "attributes": "",
            "name_admin_bar": ""
        },
        "custom_supports": ""
    }
}

Here is the query I ran (adding id to relatedPosts is when the error is thrown):

  query GET_SPECIAL($id: Int!) {
    specialBy(specialId: $id) {
      id
      specialId
      specialTitle
      specialPost {
        title
        uri
      }
      relatedPosts {
        title
        uri
        id
      }
    }
  }

And here is the logic from functions.php for that field:

register_graphql_field( $post_type_object->graphql_single_name, 'relatedPosts', [
    'type' => \WPGraphQL\Types::list_of(\WPGraphQL\Types::post_object('post')),
    'description' => __( 'Posts related to this special post', 'wp-graphql' ),
    'resolve' => function( \WPGraphQL\Model\Post $post, $args, $context, $info ) {
      $relatedIds = get_post_meta( $post->ID, 'relateds', true );
      $posts = array();
      if( is_array($relatedIds) ) {
        foreach( $relatedIds as $post_id ) {
          $thisPost = get_post($post_id);
          $posts[] = $thisPost;
        }
      }
      return ! empty( $posts ) ? $posts : array();
    }
  ]);
}

When running that query with id under relatedPosts, I get this error:

"errors": [
    {
      "debugMessage": "Cannot return null for non-nullable field Post.id.",
      "message": "Internal server error",
      "category": "internal",
      "locations": [
        {
          "line": 13,
          "column": 7
        }
      ],
      "path": [
        "specialBy",
        "relatedPosts",
        0,
        "id"
      ]
    },

Note: I did anonymize the code a bit, "special" and "relatedPosts" are values I changed from the actual code, but I believe I was consistent everywhere. If something doesn't work by direct copy and paste, it was probably just a typo when I made the modifications.

@jasonbahl
Copy link
Collaborator

@paulisloud ok, I see what's up, and probably need to document this better. . .

Since introducing the Model Layer, instead of returning raw WP_Post objects in your custom resolvers, you'll need to return an instance of a Model. This will ensure the objects go through the capability checks centrally and make sure we're not leaking private data.

So, instead of returning a list of WP_Post, you would want to return a list of WPGraphQL\Model\Post()

Something like this should work:

'resolve' => function( \WPGraphQL\Model\Post $post, $args, $context, $info ) {
      $relatedIds = get_post_meta( $post->ID, 'relateds', true );
      $posts = array();
      if( is_array($relatedIds) ) {
        foreach( $relatedIds as $post_id ) {
          $posts[] = WPGraphQL\Data\DataSource::resolve_post_object( $post_id, $context );
        }
      }
      return ! empty( $posts ) ? $posts : array();
    }

This will make sure the posts are returned as a Model, and will also make use of deferred loading.

Where get_post would have made a DB call to get the post object for each ID passed, this will now make one batch SELECT to the DB to get all post objects, so this will be more performant as well 😄

@jasonbahl
Copy link
Collaborator

I think we can consider this resolved with the info provided above. I'm going to close this, but if you find it's not actually resolved, feel free to open it back up with additional details, or create a new issue referencing this one. Thanks!

@paulgrieselhuber
Copy link
Contributor

Beautiful, thanks @jasonbahl! Figured this one was on my end.

I make a lot of calls for custom / meta fields as well. In a similar resolver context, Has the proper way to lookup those changed? I.e.:

get_post_meta( $post->ID, 'the-data', true );

@jasonbahl
Copy link
Collaborator

@paulisloud this one hasn't. I believe we cache the meta up front when asking for the post, so when you get_post_meta it should be pulling from the warmed cache instead of making additional DB requests

@jasonbahl jasonbahl reopened this Apr 26, 2019
@jasonbahl
Copy link
Collaborator

ah, I tried to click close apparently at the same time you did 😂

@seagyn
Copy link
Author

seagyn commented Apr 26, 2019

Works perfectly! Thanks a lot!

@jasonbahl
Copy link
Collaborator

dancing

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

No branches or pull requests

3 participants