I want to create a Gremlin query that only updates the vertex properties that I are not undefined in JavaScript-land. The properties on the actual vertices are defined, but my updateUser function might not actually get both firstName and lastName arguments.
Let’s say that I have ‘user’ vertices that have the ‘firstName’ and ‘lastName’ properties. When I call my update function, I may specify the new firstName of the user, the new lastName of the user, or both. I have created a query that can handle the scenario when I want to update both properties:
const updateUser = async (id, firstName, lastName) => { const { id, firstName, lastName } = userData return client.submit(`g.V().hasLabel(label).has('id', id).property(Cardinality.single, 'firstName', firstName).property(Cardinality.single, 'lastName', lastName)`, { label: 'user', id: id, firstName: firstName, lastName: lastName }).catch(error => { throw new Error(error) }) }
The problem is, that when, for instance, the firstName variable is undefined, I get the following error: ‘Unable to resolve symbol ‘firstName’ in the current context’. I want to be able to only update one of the values. How can I specify that I want to ignore undefined values?
Advertisement
Answer
You can consider whether firstName
and lastName
are defined when building the traversal string and the bindings object.
Here is some untested code to explain what I mean.
let traversal = `g.V().hasLabel(label).has('id', id)`; const bindings = { label: 'user', id: id }; if (firstName) { traversal += `.property(Cardinality.single, 'firstName', firstName)`; bindings.firstName = firstName; } if (lastName) { traversal += `.property(Cardinality.single, 'lastName', lastName)`; bindings.lastName = lastName; } client.submit(traversal, bindings);
If you are using a database that supports Gremlin bytecode, your code can be more elegant.
traversal = g.V().hasLabel(label).has('id', id); if (firstName) { traversal = traversal.property(Cardinality.single, 'firstName', firstName); } if (lastName) { traversal = traversal.property(Cardinality.single, 'lastName', lastName); }