Reputation: 3347
haven't used graphql
or mongodb
previously. What is the proper way to pass objects for the update mutation?
Since the only other way i see to pass multiple dynamically appearing parameters is to use input
type which is appears to be a bit ineffective to me (in terms of how it looks in the code, especially with bigger objects), i just pass the possible values themselves. however in this case i need to dynamically construct updateObject
, which again, going to get messy for the bigger models.
for example now i did:
Mutation: {
updateHub: async (_, { id, url, ports, enabled }) => {
const query = {'_id': id};
const updateFields = {
...(url? {url: url} : null),
...(ports? {ports: ports} : null),
...(enabled? {enabled: enabled} : null)
};
const result = await HubStore.findByIdAndUpdate(query, updateFields);
return {
success: !result ? false : true,
message: 'updated',
hub: result
};
}
}
any advise on the better way to handle this?
thanks!
Upvotes: 1
Views: 1293
Reputation: 1817
It appears your code could benefit from using ES6 spread syntax -- it would permit you to deal with an arbitrary number of properties from your args
object without the need for serial tertiary statements.
Mutation: {
updateHub: async (_, { id, ...restArgs } ) => {
const query = {'_id': id};
const updateFields = { ...restArgs };
const result = await HubStore.findByIdAndUpdate(query, updateFields);
return {
success: !result ? false : true,
message: 'updated',
hub: result
};
}
}
If for some reason you need to explicitly set the undefined properties to null
in your object, you could possibly use some a config obj and method like defaults
from the lodash library as shown below:
import { defaults } from 'lodash';
const nullFill = { url: null, ports: null, enabled: null }; // include any other properties that may be needed
Mutation: {
updateHub: async (_, { id, ...restArgs } ) => {
const query = {'_id': id};
const updateFields = defaults(restArgs, nullFill);
const result = await HubStore.findByIdAndUpdate(query, updateFields);
return {
success: !result ? false : true,
message: 'updated',
hub: result
};
}
}
Also, FWIW, I would consider placing the dynamic arguments that could be potentially be updated on its own input type, such as HubInput
in this case, as suggested in the graphql docs. Below I've shown how this might work with your mutation. Note that because nothing on HubInput is flagged as requird (!
) you are able to pass a dynamic collection of properties to update. Also note that if you take this appraoch you will need to properly destructure your args
object initially in your mutation, something like { id, input }
.
input HubInput {
url: String
ports: // whatever this type is, like [String]
enabled: Boolean
// ...Anything else that might need updating
}
type UpdateHubPayload {
success: Boolean
message: String
hub: Hub // assumes you have defined a type Hub
}
updateHub(id: Int, input: HubInput!): UpdateHubPayload
Upvotes: 1