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.
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.