0
votes

I am trying to use slug as url but its not working. I get error in console something like this.

[GraphQL error]: Message: Variable "$slug" of required type "String!" was not provided., Location: [object Object], Path: undefined

This is my code. Although it is working fine if i use id instead of slug. I am getting these data from wordpress wp-graphql api.

graphql/queries/post.js

import gql from 'graphql-tag';    
export const SinglePostDetail = gql`
  query SinglePostDetail($slug: String!) {
    postBy(slug: $slug) {
      id
      slug
      title
      date
      content
      categories{
        nodes {
          name
        }
      }
      author {
        name
      }
      featuredImage {
        sourceUrl
      }
    }
  }
`;

views/postDetail.js

import React, {Component} from 'react';
import { graphql } from 'react-apollo'
import { SinglePostDetail } from '../graphql/queries/posts'
import Layout from '../components/layout';
import Loader from '../components/Loader/loading';
import './postDetail.scss';

class PostDetail extends Component {   
    constructor () {
        super()
        this.renderPost = this.renderPost.bind(this)
    }
     render() {
         const isLoading = this.props.data.loading
         return (
             <Layout>
                 {isLoading && <Loader/>}
                 {!isLoading && this.renderPost()}
             </Layout>
         )
     }
     renderPost () {
    const post = this.props.data.postBy
    console.log(post);
    const date = new Date(post.date).toLocaleDateString()
    return (
      <div className=" container has-text-centered postdetail__wrapper">
        <h2 className="subtitle">{post.author.name}</h2>
        <h1 className="title is-2">{post.title}</h1>

        <h5 className="subtitle is-7">{post.categories.nodes.name}</h5>
        <h5 className="subtitle is-7">{date}</h5>
        <img
            alt={post.title}
            src={post.featuredImage && post.featuredImage.sourceUrl}
        />
        <div className="postdetail__content" dangerouslySetInnerHTML={{ __html: post.content }} />
      </div>
    )
  }
  }



export default graphql(SinglePostDetail, {
    options: ({match}) => ({variables: {slug: match.params.slug}})
})(PostDetail);

Routes.js

import React from 'react'
import { BrowserRouter,Route, Switch} from 'react-router-dom';
import Home from './views/Home';
import About from './views/About';
import Contact from './views/Contact';
import Category from './views/Category';
import PostDetail from './views/PostDetail';
import Blog from './views/Blog';

function Routes() {
  return (
    <BrowserRouter>
      <Switch>
          <Route path="/" exact component={Home}/>
          <Route path="/about" component={About}/>
          <Route path="/blog" component={Blog}/>          
          <Route path='/category/:slug' component={Category}/>
          <Route path="/post/:slug" component={PostDetail}/>
          <Route path="/contact" component={Contact}/>
      </Switch>
    </BrowserRouter>
  )
}

export default Routes

if I log props.data i get something like this.

console.log(props.data);

error: Error: GraphQL error: No resource could be found at new ApolloError fetchMore: ƒ ()
loading: false
networkStatus: 7
refetch: ƒ ()
startPolling: ƒ ()
stopPolling: ƒ ()
subscribeToMore: ƒ ()
updateQuery: ƒ ()
variables:
slug: "cG9zdDo1NA=="
__proto__: Object
__proto__: Object
1
The error indicates that the value for the slug variable is undefined, so you're likely not passing in the variable correctly. Please include the relevant code that shows how you're actually using this query inside your app.Daniel Rearden
If you log match.params.slug to the console, is it defined?Daniel Rearden
it says undefinedaditya kumar
but it is working fine in graphiqladitya kumar
This is not a GraphQL issue. The point is that you're asking for a param that apparently doesn't exist. What's the path for the Route component that's being matched by your router? Assuming you're using react-router, the path of the matched route would need to include :slug in order for match.params.slug to be defined. For example, if your path is /foo/:id, then match.params.id will be defined. If your path is /foo/:bar then match.params.bar will be defined.Daniel Rearden

1 Answers

3
votes

You're passing a Relay Global ID as a slug. That why it works when you use the id parameter instead.

slug: "cG9zdDo1NA==" <- This is what you're passing as a $slug. You probably have an error in how you're navigating to the page. Check out your NavLink or Link component if you're using one.

Either change to the actually post slug or modify your query like so

import gql from 'graphql-tag';    
export const SinglePostDetail = gql`
  query SinglePostDetail($id: ID!) {
    post(id: $id) {
      id
      slug
      title
      date
      content
      categories{
        nodes {
          name
        }
      }
      author {
        name
      }
      featuredImage {
        sourceUrl
      }
    }
  }
`;

[GraphQL error]: Message: Variable "$slug" of required type "String!" was not provided. <- This error is because the what being passed is of the type ID.