I have union type PaymentTerm:
type PaymentTerm =
| { type: 'AdvancePayment' }
| { type: 'PaymentGoal'; netPaymentDays: number }
I want to validate it using Joi.alternatives:
Joi.object({
type: Joi.string().required().valid('AdvancePayment')
}),
Joi.object({
type: Joi.string().required().valid('PaymentGoal'),
netPaymentDays: Joi.number().required().messages({
'any.required': '{{#label}} is required'
})
})
)
const { error, value } = schema.validate({
type: 'PaymentGoal'
})
Now I would expect to get "netPaymentDays" is required but I get "value" does not match any of the allowed types.
How can I get the "nested" errors instead of the generic ones for the alternatives?
You've mentioned the correct way to resolve this but I can't see it being used in your example.
I want to validate it using Joi.alternatives
A possible solution for your schema would be:
Joi.object().keys({
type: Joi.string().valid('AdvancePayment', 'PaymentGoal').required(),
netPaymentDays: Joi.alternatives().conditional('type', {
is: 'PaymentGoal',
then: Joi.number().required(),
otherwise: Joi.forbidden()
})
});
I'm currently trying GraphQL with NodeJS and I don't know, why this error occurs with the following query:
{
library{
name,
user {
name
email
}
}
}
I am not sure if the type of my resolveLibrary is right, because at any example I had a look at they used new GraphQL.GraphQLList(), but in my case I really want to return a single user object, not an array of users.
My code:
const GraphQL = require('graphql');
const DB = require('../database/db');
const user = require('./user').type;
const library = new GraphQL.GraphQLObjectType({
name: 'library',
description: `This represents a user's library`,
fields: () => {
return {
name: {
type: GraphQL.GraphQLString,
resolve(library) {
return library.name;
}
},
user: {
type: user,
resolve(library) {
console.log(library.user);
return library.user
}
}
}
}
});
const resolveLibrary = {
type: library,
resolve(root) {
return {
name: 'My fancy library',
user: {
name: 'User name',
email: {
email: 'test#123.de'
}
}
}
}
}
module.exports = resolveLibrary;
Error:
Error: Expected Iterable, but did not find one for field library.user.
So my library schema provides a user field which returns the right data (the console.log is called).
I ran into this problem as well. It appears that what you're returning from your resolver doesn't match the return type in your schema.
Specifically for the error message Expected Iterable, but did not find one for field library.user., your schema expects an array(Iterable) but you aren't returning an array in your resolver
I had this in my schema.js:
login(email: String, password: String): [SuccessfulLogin]
I changed that to:
login(email: String, password: String): SuccessfulLogin
Notice the square brackets around "SuccessfulLogin". It's up to you whether you want to update the resolver return type or update the schema's expectations
I guess your user is an instance of GraphQLList that is why the field user is expecting to resolve to an iterable object.
I had the same problem. I was using find instead filter.
I ran into the same issue but i was using GraphQL with Go.
Solution:
I mentioned the return type to be a list( or you can say an array), but my resolver function was returning an interface and not a list of interfaces.
Before it was =>
Type: graphql.NewList(graphqll.UniversalType)
Later i changed it to =>
Type: graphqll.UniversalType
graphqll.UniversalType : 'graphqll' is the name of my user-defined package and 'UniversalType' is the GraphQL object i have created.
The previous structure of graphql object was :
var GetAllEmpDet = &graphql.Field{
Type: graphql.NewList(graphqll.UniversalType),
Resolve: func(params graphql.ResolveParams) (interface{}, error) {
...
...
// Your resolver code goes here, how you handle.
...
return models.Universal, nil // models.Universal is struct and not list of struct so it gave that error.
},
}
It worked when i changed this to:
var GetAllEmpDet = &graphql.Field{
Type: graphqll.UniversalType,
Resolve: func(params graphql.ResolveParams) (interface{}, error) {
...
...
// Your resolver code goes here, how you handle.
...
return models.Universal, nil // models.Universal is struct and not list of struct so it gave that error.
},
}
It's usually a simple mistake. Caused by declaring in the schema a List instead of a Field. The reverse will happen if you interchange. An example from Django-graphene. Switch from this:
my_query_name = graphene.List(MyModelType, id=graphene.Int())
to this:
my_query_name = graphene.Field(MyModelType, id=graphene.Int())
In my case it was related to django-graphene I didn't have a resolve method defined.
class SomeNode(DjangoObjectType):
things = graphene.List(ThingNode)
def resolve_things(self, info, **kwargs):
return self.things.all()
For me, it was a simple fix.
items: {
type: new GraphQLList(VideoType),<-- error
resolve(parentValue, args) {
const url = 'www'
return axios.get(url)
.then(res => res.data);
}
}
and change it to
items: {
type: VideoType,
resolve(parentValue, args) {
const url = 'www'
return axios.get(url)
.then(res => res.data);
}
}
I faced the same issue. For me, it was an issue with Mongo DB model.js file.
GraphQL kept throwing that error because my model was saving the field as an object whereas graphQL was returning it as an array.
The code that caused the error was this.
tableHeaders: {
text: {
type: String,
required: false,
},
align: {
type: String,
required: false,
},
sortable: {
type: Boolean,
required: false,
},
value: {
type: String,
required: false,
},
},
It was corrected to the following.
tableHeaders: [
{
text: {
type: String,
required: false,
},
align: {
type: String,
required: false,
},
sortable: {
type: Boolean,
required: false,
},
value: {
type: String,
required: false,
},
},
],
Changing type from object to array fixed it.
i had the same issue i was using findOne and that seems like the issue that didnt worked. i changed to find and it worked
#Query(()=> [Post])
async getSinglePost(
#Arg('post_id') id: string,
){
/*
const post = await getConnection().getRepository(Post).findOne({uuid:postuid})
console.log(post);
return post
*/
const post = Post.find({uuid:id})
return post
}
This simply results due to the import error
earlier code
const books =require('./data')
// Resolvers define the technique for fetching the types defined in the
// schema. This resolver retrieves books from the "books" array above.
const resolvers = {
Query: {
books(){
return books;
},
},
}
module.exports = { resolvers };
just replace the import statement with
const {books} =require('./data')
as you had ex
I am trying to retrieve a document after it is created since Firestore does not return a created document. I do get the document Reference ID each time, however, when I turn around and use it, the promise is resolved but the retuning object is non-existent it seems.
Here is my code, the part I am struggling with is the section that is nested within the first Add call to Firestore
ideasRef
.add({
ideaId: req.body.ideaId,
title: req.body.title,
description: req.body.description,
category: req.body.category,
competitorHasIt: req.body.competitorHasIt || false,
createdAt: new Date(),
createdBy: {
email: req.body.user.email,
fullName: `${req.body.user.firstName} ${req.body.user.lastName}`,
location: req.body.user.location
},
deactivated: false
})
.then(docRef => {
console.log(docRef.id)
ideasRef
.get(docRef.id)
.then(idea => {
console.log("first run")
console.log(idea.exists())
console.log(idea.data())
console.log("do those even run?")
})
What is outputted in the console is the docRef.id value and "first run". What I expected to happen it to see the 3 subsequent console.logs as well that contains information about idea
Any advice on what I am overlooking would be greatly appreciated, my end goal is to get help and realizing why my idea object seems to silently cause issues. I do not see any errors in the terminal.
This ended up being the working version.
ideasRef
.add({
ideaId: req.body.ideaId,
title: req.body.title,
description: req.body.description,
category: req.body.category,
competitorHasIt: req.body.competitorHasIt || false,
createdAt: new Date(),
createdBy: {
email: req.body.user.email,
fullName: `${req.body.user.firstName} ${req.body.user.lastName}`,
location: req.body.user.location
},
deactivated: false
})
.then(docRef => {
console.log(docRef.id)
ideasRef
.doc(docRef.id)
.get()
.then(idea => {
console.log("first run")
console.log(idea.exists())
console.log(idea.data())
console.log("do those even run?")
})
i can't find a way to test form yup validation:
it('displays error on submit if name is empty', async () => {
const wrapper = mount(<MyFormik/>)
const getForm = () => wrapper.find('form')
wrapper.find('input[name="name"]').simulate('change', {
persist: () => {},
target: {
name: 'name',
value: ''
}
})
wrapper
.find('MyInnerForm')
.props()
.submitForm()
await wait(0) // await next tick or even 1s...
wrapper.update()
expect(
wrapper
.update()
.find('.error')
.exists()
)
.toBeTruthy() // FALSE!
})
No matter if i wait after submit, update wrapper errors prop is always empty.
And the solution here are not working for me:
https://github.com/jaredpalmer/formik/issues/1146
https://github.com/jaredpalmer/formik/issues/110
Looks like wrapper won't update
Here's the log of formik props after submit:
{ errors: {},
label: '',
name: 'name',
type: 'text',
values: { name: '' },
touched: { name: true },
isValidating: false,
status: undefined,
initialValues: { name: '' },
validateOnChange: true,
validateOnBlur: true } }
...
submitCount: 1,
isValid: false,
You can validate the form values directly on your validation schema.
const yup = require('yup')
const contactSchema = yup.object({
name: yup.string()
.required(),
age: yup.number()
.required()
.positive()
.integer()
})
const errors = await contactSchema.validate({
name: 'Kenneth',
age: -35.5
}).catch(function(err) {
return err
});
console.log("errors", errors);
https://runkit.com/kluplau/5defa8cd122cf6001a3034c7
Without seeing your component I'm not entirely sure what's going wrong. This is likely not to be working:
wrapper
.find('MyInnerForm')
.props()
.submitForm()
If your component MyInnerForm contains a Formik form calling submitForm() there will not cause Formik's validation to run. I would instead do something like this:
wrapper.find("form").simulate("submit");
However if that isn't solving your issue I made a full example that you can have a look at here.
Here my schema :
var countries = new Schema({
name: String,
capital: String,
body: String,
flag: {data: Buffer, contentType: String },
population: String,
currency: String
});
I want to select the fields name and capital.
Here my query:
countries.find({}, 'name capital', { skip: rand, limit: 1}, function(err, result){
if (err) return handleError(err);
console.log('Country :' + result);
callback(null, result);
});
But result print the entire document.
result.name is undefined.
I tried different syntaxes, like
countries.find({}, {'name':1, 'capital':1}, ....
But nothing is selected.
Any ideas?
find() returns an array of results, even though you limit it to 1.
That's probably why your result.name is undefined. So to access your name or capital, you have to use:
console.log("Country name:", result[0].name);
console.log("Country capital:", result[0].capital);
Maybe you want to use findOne(), which doesn't return an array but the object directly.
And both syntaxes should work, name capital and { name: 1, capital: 1 }.