korus90
December 30, 2016, 10:37pm
1
Hi all,
I’m struggling to get my ‘slug’ prop to pass to my graphql query, I receive this message:
POST http://localhost:3000/graphql 400 (Bad Request)
HTTPFetchNetworkInterface.fetchFromRemoteEndpoint @ modules.js?hash=2b87763…:28082
(anonymous) @ modules.js?hash=2b87763…:28099
(anonymous) @ meteor.js?hash=e3f53db…:1105
modules.js?hash=2b87763…:37485 Error in observer.error
Error
And here are the relevant bits of my code:
My route:
<Route path='/ad/:slug' component={ SingleAdvert } />
The component:
import React from 'react';
import { graphql } from 'react-apollo';
import { withRouter } from 'react-router';
import gql from 'graphql-tag';
class SingleAdvertComponent extends React.Component {
constructor( props ) {
super( props );
}
componentDidMount() {
console.log( this.props.params.slug );
}
render() {
return (
<div className="cont">
<h1 className="fw300 ttu tc">Advert!</h1>
</div>
);
}
}
// Define the graphql query to retrieve the advert
const theAdvert = gql`
query singleAdvert {
singleAdvert ( slug: $slug ) {
title,
slug,
type,
image,
excerpt,
owner
}
}
`;
// Use the graphql container to run the query
const SingleAdvert = graphql( theAdvert, {
options: ( { slug } ) => ({
variables: { slug }
}),
})( SingleAdvertComponent );
// Export the component
export default SingleAdvert;
The props are being passed into the SingleAdvertComponent
properly, as the slug is being posted into the console. But I’ve tried a lot and can’t get the slug to go into the query.
I followed the guides and docs from Apollodata as you can probably see, but having no luck!
Any help will be appreciated as always.
Cheers
ric0
January 1, 2017, 11:46am
2
Try this:
const theAdvert = gql`
query singleAdvert ($slug: String) {
singleAdvert ( slug: $slug ) {
title,
slug,
type,
image,
excerpt,
owner
}
}
`;
Hi @ric0 thanks for the suggestion! I’d already tried that, but it didn’t work (I also just put it back in, still no luck).
I hate to single anyone out, but @sashko you seem to be the dogs bollocks when it comes to helping with Apollo, any suggestions on your side?
Any other suggestions @ric0 ? Pulling my hair out a bit here as no idea what’s causing the error messages above
ric0
January 2, 2017, 2:32pm
4
Mhmm, very strange indeed.
Does this very same query work on localhost:3000/graphiql?
Bad Request 400 might be something about the formatting of the query.
On localhost:3000/graphiql you should get a more meaningful error.
Thanks for the help @ric0 !
Ok, so this query:
{
singleAdvert ( slug: "test-advert" ) {
id
image
content
excerpt
owner
title
type
slug
}
}
at localhost:3000/graphiql (which should work as I have a slug with that value?) gives me the following:
{
"errors": [
{
"message": "Unknown argument \"slug\" on field \"singleAdvert\" of type \"Query\".",
"locations": [
{
"line": 2,
"column": 17
}
]
}
]
}
So it might be the resolver function / schema. Which are:
singleAdvert( _, args ) {
return Advert.findOne( { where: args } );
}
And
export default typeDefs = [`
type Advert {
id: ID!
type: String!
title: String!
slug: String!
image: String!
content: String!
excerpt: String!
owner: String!
}
type Query {
adverts: [Advert]
singleAdvert: Advert
}
type Mutation {
createAdvert (
type: String!
title: String!
slug: String!
image: String!
content: String!
excerpt: String!
owner: String!
): Advert
}
schema {
query: Query
mutation: Mutation
}
`];
Any more suggestions? Again many thanks for your help!
ric0
January 3, 2017, 7:38am
6
type Query {
singleAdvert(slug: String): Advert
}
singleAdvert( _, args ) {
return Advert.findOne( { where: args.slug } );
}
OR
singleAdvert( _, {slug} ) {
return Advert.findOne( { where: slug } );
}
1 Like
Ok, pretty much there now but the query to the database isn’t quite right.
Here is the resolver now:
// Single advert display
singleAdvert( _, { slug } ) {
return Advert.findOne( { where: { slug: slug } } );
},
But the resulting query to the database ends up like this (as an example):
SELECT "id" FROM "adverts" AS "advert" WHERE "advert"."slug" = 'a-test-advert' LIMIT 1;
Of course, it’s the “advert”.“slug” bit that’s wrong! It should just be “slug” and then it works.
Any idea why it’s doing this? Again many thanks for your help as I’d be way further behind without it
[EDIT] I’m using Sequelize as the database connector. Here are their own docs for ‘where’ . So the above ‘should’ work but doesn’t
ric0
January 3, 2017, 8:16pm
8
Sorry, never used sequalize
In any case try:
WHERE "advert.slug" = 'a-test-advert'
Hi @ric0 ,
Just letting you know I got this sorted! Here is my solution (bare in mind I use Sequelize, as mentioned above ):
Resolver:
// Single advert display
singleAdvert( _, { slug } ) {
return Advert.findOne({
where: Sequelize.where( Sequelize.col( 'slug' ), slug )
});
},
Then, because the resulting query doesn’t return an array (like a findAll does), the component stuff ends up like this:
SingleAdvertComponent.propTypes = {
data: React.PropTypes.shape({
singleAdvert: React.PropTypes.object,
}).isRequired
};
// Define the graphql query to retrieve the advert
const theAdvert = gql`
query singleAdvert ( $slug: String ) {
singleAdvert ( slug: $slug ) {
id,
title,
slug,
type,
image,
content,
owner
}
}
`;
// Use the graphql container to run the singleAdvert query
const SingleAdvert = graphql( theAdvert, {
options: ( props ) => ({
variables: {
slug: props.params.slug
}
}),
})( SingleAdvertComponent );
// Export the component
export default SingleAdvert;
After that, you can access the content as you would any other object. HOWEVER, it will give an undefined error unless you do a check such as:
if( this.props.data.loading == false ) {
const advert = this.props.data.singleAdvert;
// Do some stuff
}
So yeah, all good! Thanks a lot for all your help and suggestions
2 Likes
ric0
January 4, 2017, 1:27pm
10
Happy to hear that
And thank you for sharing here the final solution. I’m sure it’ll help other people, too.
1 Like