diff --git a/nodes/persistent-value.js b/nodes/persistent-value.js index 9b11c3d..da5e534 100644 --- a/nodes/persistent-value.js +++ b/nodes/persistent-value.js @@ -124,15 +124,17 @@ module.exports = function(RED) { currentValue = context.get(contextKey, node.valueConfig.storage); } - // Apply default value if context contains no value - if (currentValue === undefined) { - currentValue = node.valueConfig.default; + return currentValue; + } - if (node.valueConfig.datatype === kConfigDatatypeJson) { - currentValue = JSON.parse(currentValue); - } + function getDefaultValue(node) { + let value = node.valueConfig.default; + + if (node.valueConfig.datatype === kConfigDatatypeJson) { + value = JSON.parse(value); } - return currentValue; + + return value; } function setContext(node, context, contextKey, newValue) { @@ -353,7 +355,17 @@ module.exports = function(RED) { const context = getUsedContext(node); const contextKey = getContextKey(node); + // Get value from context store let currentValue = getContext(node, context, contextKey); + + // If no value is present in context store, get the default value + let currentValueIsDefault = false; + if (currentValue === undefined) { + currentValueIsDefault = true; + currentValue = getDefaultValue(node); + } + + // Deep clone if option is enabled currentValue = deepCloneIfEnabled(node, currentValue); if (!compareToConfiguredDatatype(node, currentValue)) { @@ -389,7 +401,10 @@ module.exports = function(RED) { addPreviousValue(node, msg, currentValue); updateCollectedValues(node, msg, inputValue, currentValue); - if (!isDeepStrictEqual(inputValue, currentValue)) { + // Only write context if: + // - current value is a default value (allow writing of input values equal to default) + // - input value differs from the current value + if (currentValueIsDefault || (!isDeepStrictEqual(inputValue, currentValue))) { setContext(node, context, contextKey, inputValue); onChangeMsg = msg; } diff --git a/test/persistent_value_spec.js b/test/persistent_value_spec.js index cb95f06..0ace1d7 100644 --- a/test/persistent_value_spec.js +++ b/test/persistent_value_spec.js @@ -704,6 +704,36 @@ describe('persistent value node', function() { }); }); + it('should write to the context storage even if the input value is equal to the default value', function(done) { + const testedStorage = StorageMemory; + + const flow = structuredClone(FlowNodeAllVariants); + flow[1].values[2].storage = testedStorage; + flow[0].valueId = ConfigValueIdString; + flow[0].command = CommandWrite; + + helper.load([configNode, valueNode], flow, function() { + const v = helper.getNode(NodeIdPersistentValue); + const h = helper.getNode(NodeIdHelperCurrentValue); + + const simulatedInput = flow[1].values[2].default; // Equal to default value + + setContextValue(v, undefined, testedStorage); // Clear the context + + h.on(InputFunction, function(msg) { + try { + msg.should.have.property(PropertyPayload, simulatedInput); + const contextValue = getContextValue(v, testedStorage); + contextValue.should.be.equal(simulatedInput); + done(); + } catch (err) { + done(err); + } + }); + v.receive({payload: simulatedInput}); + }); + }); + it('should write to the context storage from non-default input msg property', function(done) { const flow = structuredClone(FlowNodeAllVariants); flow[0].valueId = ConfigValueIdString;