I'm trying to make a field in a form required if my array contains a certain string.
For example, the field 'spouseName' should be required if the array familyMembers contains 'spouse'. Is it possible to use the .when() function to check the values in array? I'm using it to check the value of strings in other parts of the forms like this:
jobTitle: Yup.string().when("jobStatus", {
is: "employed",
then: Yup.string().required(requiredError)
})
is there a way to do something like:
spouseName: Yup.string().when("familyMembers", {
contains: "spouse",
then: Yup.string().required(requiredError)
})
Instead of passing the second parameter as a object, you could pass it as a function that receives the value of the field from the first parameter (in your case, the value of familyMembers) and the schema to be modified (in your case, add required).
You can see how to do this in the docs mixed.when (It's the last example).
e.g. from the docs
yup.object({
isBig: yup.boolean(),
count: yup.number().when('isBig', (isBig, schema) => {
return isBig ? schema.min(5) : schema.min(0);
}),
});
So in your case, it should be something like
spouseName: Yup.string().when("familyMembers", (familyMembers, schema) => {
// if it includes 'spouse'
return familyMembers.includes('spouse') ?
Yup.string().required(requiredError) : // add required validation
schema; // don't change anything
}),
})
You can do other logic inside the function and also return diferent schema types.
Related
I'm trying to modify data on save of a particular field in KeystoneJS 5. The resolveInput field hook seems a good way to do this. It's the example that's given in the docs above:
const resolveInput = ({
operation,
existingItem,
originalInput,
resolvedData,
context,
actions,
}) => {
// Input resolution logic
// Object returned is used in place of resolvedData
return resolvedData;
};
The return of resolveInput can be a Promise or an Object. It should
resolve to the same structure as the resolvedData. The result is
passed to the next function in the execution order.
Thus, the definition of the field in my list is
text: {
type: Wysiwyg,
hooks: {
async resolveInput({ originalInput,resolvedData }) {
console.log('resolvedData');
console.log(resolvedData);
return resolvedData;
}
}
and to get started I'm just returning the resolvedData argument that's passed in, which, according to the docs is
resolvedData Object The data received by the GraphQL mutation plus defaults values
However, I get the following error every time
GraphQLError
Cast to string failed for value "{ text: '<p><img src="static/blop.jpg" alt="" width="580" height="388" /><img src="static/blop.jpg" alt="" /></p>' }" at path "text"
I'm unsure what the issue is or how to solve it -- I'm simply returning the same data that's passed in. When I remove the hook, all works fine.
Edit
I believe the answer is that one does not return the entire resolvedData object, but instead the field on that object whose hook you are in. Thus, in the case below, one would return resolvedData.text (or resolvedData.title). I believe the docs could be improved, since it would seem that one returns the entire resolvedData object.
You're right: according to the code in #keystonejs/keystone/lib/List/index.js one should return from resolveInput hook the field object rather than the whole resolvedData object:
// Run the schema-level field hooks, passing in the results from the field
// type hooks
resolvedData = {
...resolvedData,
...(await this._mapToFields(
this.fields.filter(field => field.hooks.resolveInput),
field => field.hooks.resolveInput({ ...args, resolvedData })
)),
};
The returning value is assigned to the field element inside resolvedData object where resolveInput hook is defined.
I have a common api for search opertaions as well as get operations if the i don't pass the search parameters the URL changes which i don't want.
for eg:
if search parameter is passed:
localhost:8080/api/search?name=harmeet
if no search parameter is passed:
localhost:8080/api/search
what i want is the url should not change whether i pass the parameter or not
for example if i don't pass parameter the url should be:
localhost:8080/api/search?name=''
The code has been written using spring boot
What URL gets called is depended on the client-side and not on the server-side. If you always want a parameter value to be something or "" when it is not passed by the client-side, you can define your controller method as:
#GetMapping("/api/search")
public Object getName(#Requestparam(value="name",required=false,defaultValue="")String name){
// your logic here
// value of 'name' variable will "" if nothing is passed
}
Just set the required field as false and use the defaultValue field to set whatever default value you want to set if the parameter is not provided in the URL call.
As per i understand you want to create API which handle two API calls.
Such as,
http://localhost:8080/search
http://localhost:8080/search?name=hermeet
I supposed you already create API in backend... Right!!!
So, There is not any issue on your logic but parameter which you defined in your method is by default required.
Which don't allow you to pass null or empty value.
You just need to allow your parameter for work with both the cases.
As following ways,
Optional<'Parameter_Type'> parameter_name
#RequestParam(value = "parameter_name", required = false) String variable
Example :
#GetMapping("/search")
public List<Entity> getSearchResult(#RequestParam(value = "parameter_name", required = false) String variable) {
if(variable!=null) {
// Get Data based on condition.
} else {
// Get All Data
}
}
#GetMapping("/search")
public List<Entity> getSearchResult(#RequestParam("parameter_name") Optinal<String> variable) {
if(variable.isPresent()) {
// Get Data based on condition.
} else {
// Get All Data
}
}
I'm using graphql with dataloader. I have this call inside a type. My problem is that when I call "categoryPhotoLoader" I want to pass user_id as a global param for every _id. Is this possible, or I have to create a concat (${_id}_${user_id}) and get inside the dataloader the first user_id of the keys? (split the string and get the user_id part of the first id)
async photoS3({_id, user_id}, _, {categoryPhotoLoader}) {
return categoryPhotoLoader.load(`${_id}_${user_id}`);
}
I would like something like that
async photoS3({_id, user_id}, _, {categoryPhotoLoader}) {
return categoryPhotoLoader.load(_id, {user_id: user_id});
}
Dataloader keys do not have to be Strings, they can be Arrays, Objects or other data types. So you can do:
categoryPhotoLoader.load({ _id, user_id })
and this Object will be passed to your batch function. If you do this, you'll want to provide a cacheKeyFn to your Loader's constructor so that dataloader can tell when two keys are equivalent. In this case, it would be simple enough to do something like:
new DataLoader(batchLoadFn, {
cacheKeyFn: ({ _id, user_id }) => ${_id}${user_id},
})
Be wary of using JSON.stringify since you want to ensure the correct order of properties in the string.
I have the following situation, my data look like this:
Product
_id: ID
name
en_US: String
nl_NL: String
weight: Number
Now I'd like to make the following GraphQL query:
{
products {
_id
name(locale:"nl_NL")
}
}
This works when adding a resolver to the productType, which returns the right locale based on the given argument. I'd rather not repeat this type + resolver all the time everytime I use this locale structure in my database. So it seems logical to create a localeType, and pass the right argument (locale) to this type, to then resolve the locale there.
For this I'd imagine to need either a Schema Type with no fields (which is not possible afaik):
const localeType = new GraphQLObjectType({
name: 'Locale',
fields: {
resolve: (locale, args) => this[args.locale],
},
});
Or a Scalar Type which accepts arguments.
Are either of these possible in GraphQL currently? And what would the syntax be?
Or any other way to solve this issue?
I was looking for a way to pass "GET" variables in codeigniter and ended up coming across this :
link text
I am wondering how to implement it.
For example :
www.website.com/query would give me every entry in the DB .
Typically I would have
www.website.com/query/?id=5 to get the equivalent entry.
when i try to do that the CI way :
www.website.com/query/id/5
I get a 404 error since it is looking for a class named id and it can't find it.
is there any way to get a step by step way to do this?
thank you.
Two good ways to achieve this using methods intended by the Codeigniter developers.
OPTION ONE:
If you always expect an "id" parameter to be present you could take advantage of a feature where you pass the value in the URI immediately after the method (function) you want to call.
Example passing /[controller]/[method]/[value]:
http://www.website.com/query/index/5
You would then access the value of "id" as an expected parameter of the function.
Class Query extends Controller {
...
// From your URL I assume you have an index method in the Query controller.
function index($id = NULL)
{
// Show current ID value.
echo "ID is $id";
...
}
...
}
OPTION TWO:
If you would like to allow many parameters to be passed in addition to ID, you could add all parameters as key=>value pairs to the URI segments in any order.
Example passing /[controller]/[method]/[key1]/[val1]/[key2]/[val2]/[key3]/[val3]:
http://www.website.com/query/index/id/5/sort/date/highlight/term
You would then parse all the URI segments from the 3rd segment ("id") forward into an array of key=>value pairs with the uri_to_assoc($segment) function from the URI Class.
Class Query extends Controller {
...
// From your code I assume you are calling an index method in the Query controller.
function index()
{
// Get parameters from URI.
// URI Class is initialized by the system automatically.
$data->params = $this->uri->uri_to_assoc(3);
...
}
...
}
This would give you easy access to all the parameters and they could be in any order in the URI, just like a traditional query string.
$data->params would now contain an array of your URI segments:
Array
(
[id] => 5
[sort] => date
[highlight] => term
)
HYBRID OF ONE AND TWO:
You could also do a hybrid of these where ID is passed as an expected parameter and the other options are passed as key=>value pairs. This is a good option when ID is required and the other parameters are all optional.
Example passing /[controller]/[method]/[id]/[key1]/[val1]/[key2]/[val2]:
http://www.website.com/query/index/5/sort/date/highlight/term
You would then parse all the URI segments from the 4th segment ("sort") forward into an array of key=>value pairs with the uri_to_assoc($segment) function from the URI Class.
Class Query extends Controller {
...
// From your code I assume you are calling an index method in the Query controller.
function index($id = NULL)
{
// Show current ID value.
echo "ID is $id";
// Get parameters from URI.
// URI Class is initialized by the system automatically.
$data->params = $this->uri->uri_to_assoc(4);
...
}
...
}
$id would contain your ID value and $data->params would contain an array of your URI segments:
You can still use GET parameters, they're just mapped to controller member function parameters:
test.com/query/id/4
Would map to the controller:
$query->id($id);
This assumes you have added a query controller and member function properly in the controllers folder in your CI application.
You can also pass your parameter values as POST parameters using a form and the CI input class.
Use $this->uri->uri_to_assoc(2) 2 is an offset, as you starting your associative array of segments in the 2nd segment. You will also need a route to make /query map to a controller and method (unless you do this in the index() method).
So, this URL:
/query/id/foo/key/bar
could be read using:
$get = $this->uri->uri_to_assoc(2);
echo $get['id']; // 'foo'
echo $get['key']; // 'bar'
It's not great, but it works.