diff --git a/src/conditionalLogicService/evaluateConditionalOptionsPredicate.ts b/src/conditionalLogicService/evaluateConditionalOptionsPredicate.ts
index b6bbd8a9..3ec75793 100644
--- a/src/conditionalLogicService/evaluateConditionalOptionsPredicate.ts
+++ b/src/conditionalLogicService/evaluateConditionalOptionsPredicate.ts
@@ -3,23 +3,77 @@ import { FormTypes, ConditionTypes } from '@oneblink/types'
 export default function evaluateConditionalOptionsPredicate({
   predicate,
   predicateElement,
-  predicateValue: value,
+  predicateValue,
 }: {
   predicate: ConditionTypes.ConditionalPredicateOptions
   predicateValue: unknown
   predicateElement: FormTypes.FormElementWithOptions
 }): boolean {
+  /**
+   * In the @oneblink/apps function formService.parseFormElementOptions dynamic
+   * lists are parsed to ensure compliance with One Blink forms. If the dynamic
+   * list options include attributes and the element has attributesMapping
+   * defined then formService.parseFormElementOptions will attempt to match each
+   * dynamic list option attribute value with an option value in the predicate
+   * element's options using the element's attributesMapping. For each attribute
+   * in the element's attrbutesMapping If a predicate option is found for a
+   * particular attribute then the optionIds property of the predicate argument
+   * of this function will be appened with either the matched option's id or
+   * value.
+   *
+   * Eg
+   *
+   *     const element = {
+   *       ...elementProps,
+   *       options: [
+   *         {
+   *           id: 'abc123',
+   *           label: 'German Shepherd',
+   *           value: 'germanShepherd',
+   *           attributes: [{ elementId: 'xyz456', optionIds: ['aaa111'] }],
+   *         },
+   *       ],
+   *     }
+   *
+   * If a predicate option is not found the optionIds property of the predicate
+   * argument will contain the dynamic list option's attribute value.
+   *
+   * Eg
+   *
+   *     const element = {
+   *       ...elementProps,
+   *       options: [
+   *         {
+   *           id: 'abc123',
+   *           label: 'German Shepherd',
+   *           value: 'germanShepherd',
+   *           attributes: [{ elementId: 'xyz456', optionIds: ['dog'] }],
+   *         },
+   *       ],
+   *     }
+   */
   return predicate.optionIds.some((optionId) => {
     const option = predicateElement.options?.find((o) => o.id === optionId)
-    if (option) {
-      if (Array.isArray(value)) {
-        return value.some((modelValue) => {
-          return modelValue === option.value
+
+    /**
+     * If the predicate element uses injected options using the {ELEMENT:Name}
+     * syntax we will not find an option. Referring to the second example above
+     * where the optionId is 'dog'. If an injected option's value parses to
+     * 'dog' then we can still match it. Ie. optionValue will be set to 'dog'
+     * and if the predicateValue is either 'dog' (radio, select, autocomplete)
+     * or ['dog'] (checkboxes, select) or {value:'dog'} (compliance) then we
+     * will return true for this predicate
+     */
+    const optionValue = option?.value ?? optionId
+    if (optionValue) {
+      if (Array.isArray(predicateValue)) {
+        return predicateValue.some((modelValue) => {
+          return modelValue === optionValue
         })
-      } else if (predicateElement.type === 'compliance' && value) {
-        return option.value === (value as { value: unknown }).value
+      } else if (predicateElement.type === 'compliance' && predicateValue) {
+        return optionValue === (predicateValue as { value: unknown }).value
       } else {
-        return option.value === value
+        return optionValue === predicateValue
       }
     } else {
       return false