First of all here is my fragment:
initialVariables: {
limit: 3,
},
fragments: {
app: () => Relay.QL`
fragment on App {
id
personnels(first: $limit) {
pageInfo {
hasNextPage
hasPreviousPage
}
edges {
cursor
node {
name
}
}
}
}
`
}
}
initial read from server works fine, but when I am calling
this.props.relay.setVariables, and trying to set limit variable I always get:
Server request for query App_AppRelayQL failed for the following reasons:
globalId is not defined
node(id:$id_0) {
^^^
in the browser console. I think it might have something to do with the schema. But not sure what, so here is my schema:
import {
GraphQLSchema,
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLList,
GraphQLID,
GraphQLNonNull
} from 'graphql';
import {
nodeDefinitions,
fromGlobalId,
globalIdField,
connectionDefinitions,
connectionFromArray,
connectionArgs,
mutationWithClientMutationId
} from 'graphql-relay';
class App {};
class Personnel {};
let app = new App();
let Personnels = [];
(() => {
let Jason = new Personnel();
let John = new Personnel();
Jason.name = 'Jason';
Jason.id = 1;
John.name = 'John';
John.id = 2;
personnels.push(YangGuoRong);
personnels.push(DengLiFang);
})();
let {nodeInterface, nodeField} = nodeDefinitions(
(gloablId) => {
const {type} = fromGlobalId(globalId);
switch(type) {
case 'App':
return app;
default:
return null;
}
},
(obj) => {
if (obj instanceof App) {
return appType;
} else if (obj instanceof Personnel) {
return personnelType;
} else {
return null;
}
}
);
let getPersonnel = (id) => personnels[id];
let getPersonnels = () => personnels;
let appType = new GraphQLObjectType({
name: 'App',
fields: () => ({
id: globalIdField('App'),
personnels: {
type: personnelConnection.connectionType,
args: connectionArgs,
resolve: (_, args) => connectionFromArray(personnels, args)
}
}),
interfaces: [nodeInterface]
});
let personnelType = new GraphQLObjectType({
name: 'Personnel',
fields: () => ({
id: {
type: new GraphQLNonNull(GraphQLID),
resolve: (obj) => obj.id
},
name: {type: GraphQLString},
}),
});
let personnelConnection = connectionDefinitions({
name: 'Personnel',
nodeType: personnelType
});
new GraphQLObjectType({
name: 'Query',
fields: {
node: nodeField,
app: {
type: appType,
resolve: () => app
},
}
}),
});
export default schema;
You made a spelling mistake in your node definitions (you wrote gloablId instead of globalId in the second line). That's why globalId is not defined.
let {nodeInterface, nodeField} = nodeDefinitions(
(gloablId) => {
const {type} = fromGlobalId(globalId);
switch(type) {
case 'App':
return app;
default:
return null;
}
},
(obj) => {
if (obj instanceof App) {
return appType;
} else if (obj instanceof Personnel) {
return personnelType;
} else {
return null;
}
}
);
When these errors appear I always try to pin down the bug by searching my code for the variable named in the error. That mostly helps
Related
I'm trying to find a specific data based on the id in graphql.
But it is returning null .
I have also tried the mutation. Here is also it is returning null.
What's wrong with this below code.
const { ApolloServer } = require("#apollo/server");
const { startStandaloneServer } = require("#apollo/server/standalone");
const students = [
{
name: "langesh",
roll: 131,
},
{
name: "ram",
roll: 134,
},
];
const typeDefs = `#graphql
type Student {
name: String,
roll: Int,
}
type Query {
students: [Student]
student(roll: Int) : Student
}
`;
const resolvers = {
Query: {
students: () => students,
student: (parent, roll) => {
return students.find((s) => s.roll === roll);
},
},
};
const server = new ApolloServer({ typeDefs, resolvers });
async function startServer() {
const { url } = await startStandaloneServer(server, {
listen: {
port: 8000,
},
});
console.log(`url : ${url}`);
}
startServer();
You need to destructure the args in your resolver.
Instead of:
student: (parent, roll) => {
return students.find((s) => s.roll === roll);
}
do:
student: (parent, { roll }) => {
return students.find((s) => s.roll === roll);
}
I have a GraphQL mutation that adds a book. I want to check if the author given exists yet and if not, add that author with a different mutation. Is this possible?
Mutation: {
addAuthor: (root, args) => {
const author = { ...args, id: uuid() }
authors = authors.concat(author)
return author
},
addBook: (root, args) => {
const existingAuthor = authors.filter(author => author.name === args.author).length > 0
if (!existingAuthor) {
addAuthor({ name: args.author }) /// This is how I want to call a mutation within my mutation
}
const book = { ...args, id: uuid() }
books = books.concat(book)
return book
}
}
Right now, this approach throws an error from the Apollo Studio Explorer:
"path": [
"addBook"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"ReferenceError: addAuthor is not defined"
Factor out your addAuthor function and use it in both places:
Mutation: {
addAuthor: _addAuthor,
addBook: (_, args) => {
const existingAuthor = authors.findIndex((a) => a.name === args.author) > -1;
if (!existingAuthor) _addAuthor(null,{ name: args.author });
const book = { ...args, id: uuid() }
books = books.concat(book)
return book
}
}
const _addAuthor = (_, args) => {
const author = { ...args, id: uuid() }
authors = authors.concat(author)
return author
}
const { ApolloServer, gql } = require('apollo-server-express');
const express = require('express');
const port = process.env.PORT || 4000;
const notes = [
{ id: '1', content: 'This is a note', author: 'Adam Scott' },
{ id: '2', content: 'This is another note', author: 'Harlow Everly' },
{ id: '3', content: 'Oh hey look, another note!', author: 'Riley Harrison' }
];
const typeDefs = gql `
type Note {
id: ID
content: String
author: String
}
type Query {
hello: String
notes: [Note]
note(id: ID!): Note
}
type Mutation {
newNote(content: String!): Note
}
`;
const resolvers = {
Query:{
hello: () => 'Hello World',
notes: () => notes,
note: (parent, args) => {
return notes.find(note => note.id == args.id);
},
Mutation: {
newNote: (parent, args) => {
let noteValue = {
id : String(notes.length + 1),
content : args.content,
author: 'Adam Scott',
};
notes.push(noteValue);
return noteValue;
}
}
},
}
Some people had naming issues but seems that I'm using the same in resolver as well as in schema.
Please bare with me, this is my second day in GraphQL and Express. I removed intentionally imports and assignment of express object, middleware since it does not let me post.
I think you are simply missing a curly bracket.
const resolvers = {
Query:{
hello: () => 'Hello World',
notes: () => notes,
note: (parent, args) => {
return notes.find(note => note.id == args.id);
}
}, <==== THIS IS MISSING =====>
Mutation: {
newNote: (parent, args) => {
let noteValue = {
id : String(notes.length + 1),
content : args.content,
author: 'Adam Scott',
};
notes.push(noteValue);
return noteValue;
}
}
My code looks something like this:
this.cashRegisterService
.query({
'storeName.contains': event.query,
'identifier.contains': event.query,
})
.subscribe(data => {
this.cashregisters = (data.body || []).map(cashRegister => ({
id: cashRegister.id,
name: `${cashRegister.identifier} ${cashRegister.storeName} (${cashRegister.mallName})`,
}));
});
I want to check if the identifier OR the storeName contain the event.query but what this does is to check if both of them contains the event.query. How can i do that? the method is generated by jhipster
query(req?: any): Observable<EntityArrayResponseType> {
const options = createRequestOption(req);
return this.http.get<ICashRegister[]>(this.resourceUrl, { params: options, observe: 'response' });
}
export const createRequestOption = (req?: any): HttpParams => {
let options: HttpParams = new HttpParams();
if (req) {
Object.keys(req).forEach(key => {
if (key !== 'sort') {
options = options.set(key, req[key]);
}
});
if (req.sort) {
req.sort.forEach((val: string) => {
options = options.append('sort', val);
});
}
}
return options;
};
I have routes like that:
router.get('/:projectid/, (req, res) => {
testCase.getTestCaseDetail(req.params.projectid, req.params.testcaseid, req.params.snapshotId).then(testcaseData => {
res.render('testCaseService', {
title: 'Page',
testcase: testcaseData,
layout: 'project_layout',
});
});
});
In the handler function, I have getTestCaseDetail function:
function getTestCaseDetail(projectId, id, snapshotId) {
let testCaseId = parseInt(id);
return new Promise(((resolve, reject) => {
return testCaseSchema.aggregate([
{ $match: { 'projectId': projectId, 'testCaseId': testCaseId } },
{
$lookup: {
from: snapshotInfoSchema.collection.collectionName,
localField: testCaseObj.SERVICE_ID,
foreignField: 'artifacts.id',
as: 'services',
},
},
{ $unwind: '$services' },
{
$match: {
'services.snapshot.id': snapshotId,
}
}
]).then(testCaseResult => {
resolve(addTestCasesV2(testCaseResult, snapshotId));
})
.catch(err => {
reject(err);
})
}));
}
and addTestCasesV2 function
const addTestCasesV2 = function (testcases, snapshotId) {
const result = [];
let serviceTypeMapping;
let serviceName;
let testCase = {
id: '',
testCaseId: '',
name: '',
serviceName: '',
serviceType: '',
modifiedAt: '',
testScripts: '',
snapshotId: '',
services: '',
inputs: [],
outputs: [],
};
let promiseInputResults, promiseOutputResults;
const testcasesList = lodash.map(testcases, (tc) => {
const artifacts = lodash.map(tc.services.artifacts, (art) => {
if (art.id === tc.service_id) {
serviceTypeMapping = art.processType.serviceTypeName;
serviceName = art.name;
if (!commonUtil.isUndefined(art.processParameters)) {
if (!commonUtil.isUndefined(art.processParameters.input)) {
promiseInputResults = lodash.map(art.processParameters.input, (ip) => {
let classId = commonUtil.getArtifactId(ip.classId);
return objectType.getObjectTypeByClassId(snapshotId, classId)
});
}
if (!commonUtil.isUndefined(art.processParameters.output)) {
promiseOutputResults = lodash.map(art.processParameters.output, (ip) => {
let classId = commonUtil.getArtifactId(ip.classId);
return objectType.getObjectTypeByClassId(snapshotId, classId)
});
}
}
testCase.id = tc.testCaseId;
testCase.testCaseId = tc.testCaseId;
testCase.name = tc.name;
testCase.serviceName = serviceName;
testCase.serviceType = serviceTypeMapping;
testCase.modifiedAt = tc.modifiedAt;
testCase.testScripts = tc.testScripts;
testCase.snapshotId = snapshotId;
testCase.services = tc.services;
Promise.all(promiseInputResults).then(inputItems => {
return testCase.inputs = inputItems;
});
Promise.all(promiseOutputResults).then(outputItems => {
return testCase.outputs = outputItems;
});
}
});
});
return testCase;
};
The inputs/outputs is an list of item, like that:
inputs:[
{
name: "test1",
type: "String"
},
{
name: "test2",
type: "number"
},
]
I have a problem with promise lifecycle, this is the current flow
1. Routes
2. function getTestCaseDetail
3. resolve(addTestCasesV2(testCaseResult, snapshotId));
4. addTestCasesV2 ==> return testCase but without go to 2 promise.all functions
5. resolve(addTestCasesV2(testCaseResult, snapshotId));
6. Routes
7. go back 2 promise.all functions
8. end at return testCase.outputs = outputItems;
Please see the image to more detail flow (the white number is current flow, the orange number is my expect flow)
Please advice me. Many thanks.
Your code doesn't seem correct. If testcases is an array with more than one item, your lodash.map callback will be called testcases.length time. Each time overwriting testCase.id assigned in previous callback.
Anyways, I have corrected bits of your code to make it in run order that you wanted. I have logged ==step== at various places for your help.
First Function:
function getTestCaseDetail(projectId, id, snapshotId) {
let testCaseId = parseInt(id);
return new Promise(((resolve, reject) => {
return testCaseSchema.aggregate([
{ $match: { 'projectId': projectId, 'testCaseId': testCaseId } },
{
$lookup: {
from: snapshotInfoSchema.collection.collectionName,
localField: testCaseObj.SERVICE_ID,
foreignField: 'artifacts.id',
as: 'services',
},
},
{ $unwind: '$services' },
{
$match: {
'services.snapshot.id': snapshotId,
}
}
]).then(testCaseResult => {
console.log('=======STEP 1=======');
resolve(addTestCasesV2(testCaseResult, snapshotId));//=======STEP 2=======
console.log('=======STEP 5=======')
})
.catch(err => {
reject(err);
})
}));
}
Second function
const addTestCasesV2 = function (testcases, snapshotId) {
console.log('=======STEP 2=======')
const result = [];
let serviceTypeMapping;
let serviceName;
let testCase = {
id: '',
testCaseId: '',
name: '',
serviceName: '',
serviceType: '',
modifiedAt: '',
testScripts: '',
snapshotId: '',
services: '',
inputs: [],
outputs: [],
};
let promiseInputResults, promiseOutputResults;
return Promise.resolve()
.then(()=>{
console.log('=======STEP 3=======');
const testcasesList = lodash.map(testcases, (tc) => {
const artifacts = lodash.map(tc.services.artifacts, (art) => {
if (art.id === tc.service_id) {
serviceTypeMapping = art.processType.serviceTypeName;
serviceName = art.name;
if (!commonUtil.isUndefined(art.processParameters)) {
if (!commonUtil.isUndefined(art.processParameters.input)) {
promiseInputResults = lodash.map(art.processParameters.input, (ip) => {
let classId = commonUtil.getArtifactId(ip.classId);
return objectType.getObjectTypeByClassId(snapshotId, classId)
});
}
if (!commonUtil.isUndefined(art.processParameters.output)) {
promiseOutputResults = lodash.map(art.processParameters.output, (ip) => {
let classId = commonUtil.getArtifactId(ip.classId);
return objectType.getObjectTypeByClassId(snapshotId, classId)
});
}
}
testCase.id = tc.testCaseId;
testCase.testCaseId = tc.testCaseId;
testCase.name = tc.name;
testCase.serviceName = serviceName;
testCase.serviceType = serviceTypeMapping;
testCase.modifiedAt = tc.modifiedAt;
testCase.testScripts = tc.testScripts;
testCase.snapshotId = snapshotId;
testCase.services = tc.services;
/*=======FOLLOWING IS NOT REQUIRED=======*/
// Promise.all([promiseOutputResults]).then(outputItems => {
// return testCase.outputs = outputItems;
// });
}
});
});
return Promise.all([promiseInputResults,promiseOutputResults]);
})
.then(inputItems => {//array of resolved values
console.log('=======STEP 4=======');
testCase.inputs = inputItems[0];
testCase.outputs = inputItems[1];
return testCase;
})
};
Now you can use following to extract testcase from first function:
getTestCaseDetail(myProjectId, id, mySnapshotId)
.then(testCase=>console.log(testCase))
JSfiddle for your understanding.