I am trying to use dataloader's loadMany function. But I am getting error. I already search many where but not getting any solutions. Please help me.
Here is my try-
loader.js (Here I write Loader function)-
//Models
const {Subcategory} = require("../Models/categoryModel");
module.exports.batchSubCategory = async (categoryIds) => {
const subcategory = await Subcategory.find({_id: {$in: categoryIds}});
return categoryIds.map(categoryId => subcategory.find(category => category.id === categoryId));
}
And then in Apollo Context-
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req }) => {
return {
loaders: {
subCategory: new Dataloader(keys => loaders.subCategoryLoaders.batchSubCategory(keys)),
}
}
}
});
The I call this Subcategory loader-
subCategory: async (parent, _, { loaders }) => {
const subcategory = await loaders.subCategory.loadMany(parent.subCategory.toString())
return subcategory;
}
Notice: Here I use loadMany because Here subCategory is a Array of [ids]. Here is image-
And When I run the application- I am getting this type of error-
The loader.loadMany() function must be called with Array<key> but got: 62bab157e769a7dda09ec63f,62bab15ce769a7dda09ec64a,62bab164e769a7dda09ec657.
Now I can't understand How can I solve this error. Please help me. Please give some of your valuable times to solve my problem.
Related
I am trying to write a test for an angular service which I am using with graphql & Apollo.
I'm receiving these errors: Error: Expected one matching operation for criteria "Match DocumentNode", found none.
and
Error: Expected no open operations, found 1:
foo.spec.ts
import { TestBed } from '#angular/core/testing';
import {
....
const fragment: DocumentNode = gql`
fragment SummaryDetails on SummaryDetails {
foo
...
}
`;
const summaryQuery: DocumentNode = gql`
query Summary(
) {
Summary(
) {
...SummaryDetails
}
}
${fragment}
`;
const fundDataServiceParams: FundDataServiceParams = {
foo ...
};
const expectedRawSummaryDetails: any = {
Summary: [
{
foo ...
},
],
};
const expectedSummaryDetails: SummaryDetail[] = [
{
foo ...
},
];
describe('FundSummaryServiceRegisterMethod', () => {
let controller: ApolloTestingController;
let fundSummaryService: FundSummaryService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ApolloTestingModule, HttpClientTestingModule],
});
controller = TestBed.inject(ApolloTestingController);
foo = TestBed.inject(foo);
});
afterEach(() => {
controller.verify();
});
fit('should return foodetails', (done: DoneFn) => {
fundSummaryService
.register(fragment, fundDataServiceParams)
.subscribe((foo) => {
expect(foo).toEqual(foo);
done();
});
const op = controller.expectOne(fooQuery);
expect(op.operation.variables.foo).toEqual(foo.foo);
op.flushData(expectedfoo);
});
});
Note: I tried this old post's suggestion, didn't work.
The good news for you is that in the afterEach, controller.verify() is failing meaning there is a query in queue and not all of them have been dealt with. I am thinking that your summaryQuery is slightly off where it is not matching exactly the query where the afterEach is saying is still in queue and has not been flushed.
I think you can use a different definition of expectOne from the documentation to match the query in queue. I don't have much experience with Apollo or GraphQL but try something like this for the expectOne:
const op = controller.expectOne(operation => {
// can assert some stuff on the operation like the documentation shows
return true;
});
If the above works, it most likely means that summaryQuery does not match the query that ApolloTestingController sees.
I have aproblem when test Apollo.When I try query with apollo and graphql, i want response return error and partical data, so I set property errorPolicy:'all'. But its not work. I don't no why? Help please!
Here my code:
query { animal {
name
age }, school {
name
numberfd } } `
const { loading,data,error} = useQuery(GET_DASHBOARD_DATA, {
errorPolicy:'all',
onCompleted: (res) => {console.log("complete",res)},
onError : (res,data) => {console.log("ERRRR",res,data)},
})
and i want to receive:
{
error:[...], data:[animal:[...]] }
but its only response error.Here is Apollo's doc: https://www.apollographql.com/docs/react/data/error-handling/
onError type is onError?: (error: ApolloError) => void;. You don't have data inside onError callback.
After useQuery you can add:
console.log('data', data)
console.log('error', error)
I faced the same issue with errorPolicy: 'all', I only received the partial result inside onCompleted callback of useQuery, but no errors.
I created an ErrorLink like this:
private createErrorLink = () => {
return new ApolloLink((operation, forward) => {
return forward(operation).map((response) => {
// filter out errors you don't want to display
const errors = filterSomeErrors(response.errors);
if (errors && response?.data) {
response.data.errors = errors;
}
return response;
});
});
};
Now inside my onCompleted callback I get my data as well as errors. You will have to tweak your types a bit, because seems there is no errors field on response.data by default.
Mind that if you use onError from Apollo and return something from the link, it will retry your request containing errors!
I am trying to unit test a function which makes an async call using an Axios helper instance. I have attempted multiple ways of trying to unit test this but I can not seem to find any material online which has helped. I've been stuck on this problem for a few days which is frustrating so any help would be appreciated! Below are the Axios Helper file (api.js)
api.js
import axios from 'axios'
const API = (token = null) => {
let headers = {
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-key': process.env.NEXT_PUBLIC_API_HEADER_SUBSCRIPTION_KEY
}
if (token) {
const tokenHeader = { Authorization: 'Bearer ' + token }
headers = { ...headers, ...tokenHeader }
}
const url = process.env.NEXT_PUBLIC_API_BASE_URL
const API = axios.create({
baseURL: url,
headers
})
return API
}
export default API
mocked API
export default {
post: jest.fn(() =>
Promise.resolve({
data: {}
})
),
get: jest.fn(() =>
Promise.resolve({
data: {}
})
)
}
action file
export const initiate2FA = (destinationValue) => async () => {
const twoFactorAuth = destinationValue
const res = await API().post('/foo', {
Destination: twoFactorAuth
})
return res
}
Action.test.js
import API from 'api/api'
import { initiate2FA } from 'actions/userActions'
jest.mock('api/api')
const mockedAxios = API
const dispatch = jest.fn()
describe('Initiate2FA function', () => {
it('bar', async () => {
mockedAxios.get.mockImplementationOnce(() => Promise.resolve({ status: 200 }))
const t = await dispatch(initiate2FA('test#test.com'))
console.log(t)
})
})
My issue with the above test file is that it returns an anonymous function and I do not know how to handle this to pass the unit test. The goal of the test is to make sure the function is called. I am not sure if I am approaching this the correct way or should change my approach.
Again, any suggestions would be great!
Mocking an API call is something you can mock on your own React component, instead of a function, and the best option would be to not mock anything on your component. Here you can read all about why you should not mock your API functions. At the end of the article, you're going to find a library called Mock Service Worker which you can use for your purpose.
The way you declare you have an actual HTTP called that needs to be mocked would be something like this:
rest.get('/foo', async (req, res, ctx) => {
const mockedResponse = {bar: ''};
return res(ctx.json(mockedResponse))
}),
If you just need to unit test a function, you can still use Mock Service Worker to resolve the HTTP request, and then test what happens after that. This would still be your first choice. And the test would look like:
// this could be in another file or on top of your tests.
rest.get('/foo', async (req, res, ctx) => {
const mockedResponse = {bar: ''};
return res(ctx.json(mockedResponse))
}),
// and this would be your test
describe('Initiate2FA function', () => {
it('bar', async () => {
const res = await initiate2FA('test#test.com');
expect(res).toBe({bar: '');
})
})
I am getting the following error when building Typedefs in Apollo Server:
return typeDef.definitions.some(definition => definition.kind === language_1.Kind.DIRECTIVE_DEFINITION &&
^
TypeError: Cannot read property 'some' of undefined
I tried to follow some solutions from here https://github.com/apollographql/apollo-server/issues/2961 but still, I am getting the error.
This is how I am creating the schema:
fs.readdirSync(__dirname)
.filter(dir => { console.log('dir', dir); return dir.indexOf('.') < 0 })
.forEach((dir) => {
const tmp = require(path.join(__dirname, dir)).default;
resolvers = merge(resolvers, tmp.resolvers);
typeDefs.push(tmp.types);
});
const schema = new ApolloServer({
typeDefs,
resolvers,
playground: {
endpoint: '/graphql',
settings: {
'editor.theme': 'light'
}
}
});
type.js
const Book = gql`
type Book {
title: String!
author: String!
}
`;
export const types = () => [Book];
export const typeResolvers = {
};
mutation.js
const Mutation = gql`
extend type Mutation {
addBook(book: BookInput): Book
}
`;
export const mutationTypes = () => [Mutation];
export const mutationResolvers = {
Mutation: {
addBook: async (_, args, ctx) => {
return []
}
}
};
index.js
export default {
types: () => [types, queryTypes, inputTypes, mutationTypes],
resolvers: Object.assign(queryResolvers, mutationResolvers, typeResolvers),
};
Any suggestions? What could I be missing?
I just had the same issue for the past 2 hours. I realized the file were i was instantiating my apollo server was being executed before the typedefs was created.
Simple way to test for this is to make a console.log(types, queryTypes, inputTypes, mutationTypes) right before the execution of const schema = new ApolloServer({ ....
One of them is undefined. Thanks.
After spending some time making changes, I finally got a working solution.
I had to make sure that typeDefs was an array of GraphQL Documents and not a type of [Function: types]. To do that, I removed unnecessary function syntax.
For example:
I replaced this export const types = () => [Book]; with this export const types = Book;
I replaced this types: () => [types, queryTypes, inputTypes, mutationTypes] with types: [types, queryTypes, inputTypes, mutationTypes]
... and pretty much every where I had () =>
Finally, before instantiating ApolloServer, instead of pushing tmp.types to the array of types, I used concat to use all defined graphql types in the I had defined the current file 'plus' the graphql types imported in every directory
typeDefs = typeDefs.concat(tmp.types);
I have created a small react-redux application to fetch api data with redux-thunk middleware, for some reason, the action creator function that returns dispatch is not working.
Action Creators:
export const fetchUsers = () => {
console.log('test 1');
return dispatch => {
console.log('test 2');
dispatch(fetchUserRequest);
axios
.get("https://jsonplaceholder.typicode.com/users")
.then(response => {
const users = response.data;
dispatch(fetchUserSuccess(users));
})
.catch(error => {
const errorMessage = error.message;
dispatch(fetchUsersFailure(errorMessage));
});
};
};
console.log('test 1') is working but console.log('test 2') is not working.
Here is codesanbox link
You were missing a a few things:
in userTypes you were missing there is no _ when you create const types for example export const FETCH_USER_REQUEST = "FETCH USER REQUEST"; should be export const FETCH_USER_REQUEST = "FETCH_USER_REQUEST"; also in userActions import it from userTypes not userReducers it should be import {
FETCH_USER_REQUEST,
FETCH_USER_SUCCESS,
FETCH_USER_FAILURE
} from "./userTypes";
I have also fixed your userContainer, codesandbax: codesandbax