This question already has answers here:
Why does a GraphQL query return null?
(6 answers)
Closed 3 years ago.
I tried to practised some GrahpQL and I am stuck...
I want to take one object from api list but grahpql returning null.
Used async/await doesn't help.
There is no problems with returning all list but with single element.
const axios = require('axios');
const {
GraphQLObjectType,
GraphQLInt,
GraphQLString,
GraphQLList,
GraphQLSchema
} = require('graphql');
// Country basic info
const CountryInfo = new GraphQLObjectType({
name: "CountryInfo",
fields: () => ({
name: { type: GraphQLString },
capital: { type: GraphQLString },
population: { type: GraphQLInt },
flag: { type: GraphQLString },
})
})
// Root Query
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
countryList: {
type: new GraphQLList(CountryInfo),
resolve(parent, args) {
return axios.get('https://restcountries.eu/rest/v2/all').then( res => res.data );
}
},
country: {
type: CountryInfo,
args: {
name: { type: GraphQLString }
},
async resolve(parent, args) {
const element = await axios.get(`https://restcountries.eu/rest/v2/name/${args.name}`).then(res => res.data);
return element;
}
},
},
});
module.exports = new GraphQLSchema({
query: RootQuery,
});
If you look at the response coming from the REST endpoint, what's being returned is an array of countries, and not just a single country object. Your resolver cannot return an array unless the type of the field is a List. Similarly, if the type of the field is a List, you cannot return an object in your resolver. This should work:
country: {
type: CountryInfo,
args: {
name: { type: GraphQLString }
},
async resolve(parent, args) {
const elements = await axios.get(`https://restcountries.eu/rest/v2/name/${args.name}`).then(res => res.data);
return elements[0];
}
},
Related
I want to display orderSchema in the frontend which is a subdocument. My subdocuments are objects which have a unique obiect id. As I am able to get the userSchema but not able to get orderSchema on the frontend do I need to make some changes in getServerSideProps function?
To take a deeper look you can checkout my repo - https://github.com/Sarab71/Git-optics
Model
import mongoose from 'mongoose'
const orderSchema = new mongoose.Schema({
rsph: { type: Number },
rcyl: { type: Number },
raxis: { type: Number },
lsph: { type: Number },
lcyl: { type: Number },
laxis: { type: Number },
add: { type: Number },
frame: { type: String },
lens: { type: String }
}, {
timestamps: true
});
const userSchema = new mongoose.Schema({
name: { type: String, required: true },
phone: { type: Number, required: true },
address: { type: String, required: true },
orders: [orderSchema]
}, {
timestamps: true
});
export default mongoose.models.User || mongoose.model('User', userSchema)
Api
import User from "../../../models/addUser";
import initDB from "../../../helper/initDB";
initDB()
export default async (req, res) => {
switch (req.method) {
case "GET":
await getUser(req, res)
break;
}
}
const getUser = async (req, res) => {
const { uid } = req.query
const user = await User.findOne({ _id: uid })
res.status(200).json(user)
}
FrontEnd
I am using getServerSideProps for the FrontEnd
export async function getServerSideProps({ params: { id } }) {
const res = await fetch(`${baseUrl}/api/user/${id}`)
const data = await res.json()
return {
props: { user: data }
}
}
Im trying to create a sequalized query that Searches For a Team Name & Filter To Sport Type but when I test the JSON body on Postman I get an error and its not returning the data. The JSON body matches the data that its meant to return but its not matching up.
Test on Postman
{
"searchTerm": "Kaizer fc",
"sportType": "2"
}
teams.js
const Teams = require('../models').teams;
const {sequelize, QueryTypes } = require('sequelize');
const db = require('../models')
const search = (searchTerm, sportType) => {
return new Promise(async (resolve, reject) => {
try {
console.log("Testing");
const teams = await db.sequelize.query(
`SELECT teams.name, institutions.name, addresses.line1, addresses.line2, addresses.country
FROM teams
INNER JOIN institutions
ON teams.institution_id = institutions.id
INNER JOIN addresses
ON institutions.address_id = addresses.id
WHERE teams.name like :search_name and teams.sport_type_id LIKE :sport_type`,
{
replacements: { search_name: searchTerm, sport_type: sportType },
type: QueryTypes.SELECT
}
);
return resolve(teams);
} catch (err) {
return reject(err)
}
})
}
teams.js - Models Folder
'use strict';
module.exports = (sequelize, DataTypes) => {
const teams = sequelize.define('teams', {
name: { type: DataTypes.STRING, allowNull: false },
media_id: { type: DataTypes.STRING, allowNull: true },
state_id: { type: DataTypes.INTEGER, allowNull: true },
status_id: { type: DataTypes.INTEGER, allowNull: true },
sport_type_id: { type: DataTypes.INTEGER, allowNull: false },
created_by: { type: DataTypes.INTEGER, allowNull: true, references: { model: 'users', key: 'id' } },
modified_by: { type: DataTypes.INTEGER, allowNull: true, references: { model: 'users', key: 'id' } },
primary_user_id: { type: DataTypes.INTEGER, allowNull: true, references: { model: 'users', key: 'id' } },
institution_id: { type: DataTypes.INTEGER, allowNull: true, references: { model: 'institutions', key: 'id' } },
}, {
createdAt: 'created_at',
updatedAt: 'updated_at',
indexes: [
{
unique: true,
fields: ['id']
}
],
});
return teams;
};
search.js - Controllers
const helper = require('../utils/helper');
const teamsService = require('../services/teams');
const search = async (req, res) => {
try {
const data = await teamsService.search(req.body);
console.log("TESTING");
console.log(data);
return res.send(data);
} catch (err) {
return helper.handleError(err, req, res);
}
}
module.exports = search;
search function has two arguments: searchTerm and sportType and you pass the whole req.body as a first argument so that's why it becomes a value for searchTerm and you got this error about the whole value from Sequelize.
Just extract both props from req.body OR define search with props passed by as an object:
const { searchTerm, sportType } = req.body;
const data = await teamsService.search(searchTerm, sportType);
OR
const data = await teamsService.search(req.body);
...
const search = ({ searchTerm, sportType }) => {
return new Promise(async (resolve, reject) => {
I'm not sure which part I might be doing wrong. I was hoping to get some advice.
The query I am using in GraphiQL is:
query getUser($id:Int!) {
user(id:$id) {
id
email
}
}
For the backend I am using NodeJS. I am also declaring the user type as:
const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: { type: GraphQLID },
email: { type: GraphQLString }
})
});
My root query is:
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLInt } },
resolve(parentValue, args) {
const query = `SELECT * FROM users WHERE id=$1`;
const values = [ args.id ];
dbQuery.query(query, values).then(({ rows }) => {
console.log(rows[0]);
return rows[0];
});
}
}
}
});
const schema = new GraphQLSchema({ query: RootQuery });
app.use(
'/api/v1/graphql',
graphqlHTTP({
schema: schema,
graphiql: true
})
);
What I get in return is:
{
"data": {
"user": null
}
}
I was hoping to know what I might be doing wrong that is resulting in null being returned instead of the data that I am querying from the database.
Thank you for all the help.
It will be much more clear if you use with await
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLInt } },
resolve: async(parentValue, args) {
const query = `SELECT * FROM users WHERE id=$1`;
const values = [ args.id ];
const rows = await dbQuery.query(query, values);
return rows[0];
}
}
}
});
When using a promise and returning anything inside the promise will only return the result to the promise that is executed. It will not be returning as a whole to the parent function.
You can also return the whole promise function like below
return dbQuery.query(query, values)
I'm new to GraphQL so I'm doing my first query and I'm trying to query for a nested key, email
Here is my schema
const UserLogin = new GraphQLObjectType({
name: 'UserLoginType',
fields: () => ({
login: { type: GraphQLString },
email: { type: GraphQLString },
}),
});
exports.UserType = new GraphQLObjectType({
name: 'UserType',
fields: () => ({
id: NotNullStringType,
name: { type: GraphQLString },
state: { type: GraphQLString },
login: { type: UserLogin },
}),
});
And what I'm trying to do is build a query that takes an email and searches for the UserType.login.email value and return the first value that matches that email or null.
Thanks!
Edit: In my redux/actions.js file I added:
export const fetchLoginsByEmail = (userEmail) => {
return createGraphqlAction(
{
query: `
query fetchUserByEmail($userEmail: String!) {
fetchUserByEmail(email: $userEmail) {
login {
email
}
state
name
id
}
}
`,
variables: {
userEmail,
}
},
FETCH_LOGINS_BY_EMAIL,
);
};
And in my query.js file I have this in my model.exports object:
fetchUserByEmail: {
type: UserType,
resolve: async (source, args, { user, loginId }) => {
if (!user) {
return null;
}
return serailize({
...user,
login: await getLogin(loginId),
});
},
},
It looks like you're missing the arguments parameter for your query resolver.
Update your query.js into something like:
fetchUserByEmail: {
type: UserType,
args: {
email { type: GraphQLString }
},
resolve: async (source, args, { user, loginId }) => {
// You can now use args.email here and filter your results with it
console.log(args.email);
if (!user) {
return null;
}
return serailize({
...user,
login: await getLogin(loginId),
});
},
},
This question already has answers here:
Why does a GraphQL query return null?
(6 answers)
Closed 3 years ago.
I am trying to retrieve data from an API using GraphQL and Express. For some reason, I am only getting null as a result. I am new to GraphQL so, I am unsure why it is not working. Am I missing a configuration?
Thank you in advance.
The API URL is:
https://api.tfl.gov.uk/bikepoint
server.js
const express = require('express');
const expressGraphQL = require('express-graphql')
const schema = require('./schema/schema')
const app = express();
app.use('/graphql', expressGraphQL({
schema,
graphiql: true,
}))
app.listen(4000, () => {
console.log("Listening")
});
schema.js
const graphql = require('graphql')
const axios = require('axios')
const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema
} = graphql;
const BikepointType = new GraphQLObjectType({
name: 'Bikepoint',
fields: {
id: { type: GraphQLString},
url: { type: GraphQLString},
commonName: { type: GraphQLString},
placeType: { type: GraphQLString}
}
})
const RootQuery = new GraphQLObjectType({
name: 'RootQuery',
fields: {
bikepoint: {
type: BikepointType,
args: { id: { type: GraphQLString } },
resolve( parentValue, args ) {
return axios.get(`https://api.tfl.gov.uk/bikepoint`)
.then( resp => resp.data );
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
I forgot to add the args.id.
Solution:
axios.get(`https://api.tfl.gov.uk/bikepoint/${args.id}`)