You are viewing limited content. For full access, please sign in.

Question

Question

Unknown breaking bug on form submission

asked on November 6
ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'split')
TypeError: Cannot read properties of undefined (reading 'split')
    at G.getHiddenFieldIds (main.js?v=11.0.2212.30987:1:99529)
    at main.js?v=11.0.2212.30987:1:98842
    at G.traverseStateAndFormGroup (main.js?v=11.0.2212.30987:1:97438)
    at main.js?v=11.0.2212.30987:1:97893
    at vendor.js?v=11.0.2212.30987:14:27174
    at x (vendor.js?v=11.0.2212.30987:14:14407)
    at vendor.js?v=11.0.2212.30987:14:26947
    at C (vendor.js?v=11.0.2212.30987:14:42735)
    at G.loopThroughChildren (main.js?v=11.0.2212.30987:1:97727)
    at main.js?v=11.0.2212.30987:1:97609
    at G.getHiddenFieldIds (main.js?v=11.0.2212.30987:1:99529)
    at main.js?v=11.0.2212.30987:1:98842
    at G.traverseStateAndFormGroup (main.js?v=11.0.2212.30987:1:97438)
    at main.js?v=11.0.2212.30987:1:97893
    at vendor.js?v=11.0.2212.30987:14:27174
    at x (vendor.js?v=11.0.2212.30987:14:14407)
    at vendor.js?v=11.0.2212.30987:14:26947
    at C (vendor.js?v=11.0.2212.30987:14:42735)
    at G.loopThroughChildren (main.js?v=11.0.2212.30987:1:97727)
    at main.js?v=11.0.2212.30987:1:97609
    at Me (polyfills.js?v=11.0.2212.30987:29:2262)
    at polyfills.js?v=11.0.2212.30987:29:2980
    at Z.invokeTask (polyfills.js?v=11.0.2212.30987:14:7965)
    at Object.onInvokeTask (vendor.js?v=11.0.2212.30987:2071:1669)
    at Z.invokeTask (polyfills.js?v=11.0.2212.30987:14:7886)
    at Z.runTask (polyfills.js?v=11.0.2212.30987:14:2981)
    at pe (polyfills.js?v=11.0.2212.30987:14:10411)
    at Z.invokeTask [as invoke] (polyfills.js?v=11.0.2212.30987:14:9162)
    at $ (polyfills.js?v=11.0.2212.30987:45:768)
    at ie (polyfills.js?v=11.0.2212.30987:45:1182)

I'm using Laserfiche Forms Professional Version 11.0.2212.30987
with Modern Form Designer.

I encountered the above error when I try to submit the form, it only happen like 60% of the time. Sometimes I can submit, sometimes I can not.

I do use JavaScript and hidden fields to populate/update data (since some fields like checkboxes can not be bound with rules).

How can I resolve/suppress this error so the form submission can be more stable?

Things I've tried:

- Disabling Backend Validation (No Validation) but it doesn't work (I was suspecting some of the hidden required fields causing trouble)

- Toggle Required options on hidden fields (doesn't work)

0 0

Replies

replied on November 6

Can you provide your JavaScript, or remove it temporarily to see if you have more consistent successful submissions?

1 0
replied on November 7

Temporarily commenting all the code makes the submissions more consistent. May be my JavaScript have some problem?
I perform lookup to set values to hidden fields, then use those fields to set values for checkboxes.

console.log("DEBUG")

const soNumber_fieldId = 2;
const for_fieldId = 3;

const req_OutlinePackageA_fieldId = 14;

const req_TestReports_fieldId = 18;

const req_InstructBooks_fieldId = 19;

const req_SparePLU_fieldId = 20;

const req_SolidWorks_fieldId = 22;

const req_Other_fieldId = 23;

const req_Special_Instruction = 60;

var requirements = {
    value: [],
    otherChoiceValue: ""
}

var isBinding = false;

var requirementsReady = false
const getRequirements = (fieldId, reqValue) => {
    var req = LFForm.getFieldValues({ fieldId: fieldId });
    if (!req) return;

    if (req.toLowerCase() === 'true') {
        if (!requirements.value.includes(reqValue)) {
            requirements.value.push(reqValue);
        }
    } else if (req.toLowerCase() === 'false') {
        requirements.value = requirements.value.filter(x => x !== reqValue);
    }

    else if (req.trim() !== '') {
        if (!requirements.value.includes("_other")) {
            requirements.value.push("_other")
            requirements.otherChoiceValue = req;
        }
    }
    else if (req.trim() === '') {
        requirements.value = requirements.value.filter(x => x != "_other")
        requirements.otherChoiceValue = "";
    }

    LFForm.setFieldValues({ fieldId: 4 }, requirements)
    requirement_snapshot = requirements
}

LFForm.onLookupTrigger(function () {
    LFForm.setFieldValues({ fieldId: 39 }, "")
    requirements.value = [];
    requirements.otherChoiceValue = "";

    requirementsReady = false;
}, { lookupRuleId: 1 })

LFForm.onLookupDone(function () {


    var soNumber = LFForm.getFieldValues({ fieldId: 2 })
    var taskType = LFForm.getFieldValues({ fieldId: 3 })
    if (soNumber === '' || taskType === '') {
        return
    }
    requirementsReady = true
    checkForModifications()
}, { lookupRuleId: 1 })

function checkForModifications() {
    if (!requirementsReady) return
    const revision = LFForm.getFieldValues({ fieldId: 75 })
    const currentReqs = LFForm.getFieldValues({ fieldId: 4 })
    const reqUnchanged = arraysEqualUnordered(requirements.value.filter(x => x != '_other'), currentReqs.value.filter(x => x != '_other'))
    const otherUnchanged = requirements.value.includes('_other') || requirements.value.includes('_other')
    const otherValueUnchanged = requirements.otherChoiceValue == currentReqs.otherChoiceValue
    const specialInstructionUnchanged = LFForm.getFieldValues({ fieldId: req_Special_Instruction }) == LFForm.getFieldValues({ fieldId: 5 })

    const isDirty = !(reqUnchanged && otherUnchanged && otherValueUnchanged && specialInstructionUnchanged);
    if (revision && revision != '' && isDirty) {
        LFForm.setFieldValues({ fieldId: 39 }, "Modified")
    }
    else if (isDirty) {
        LFForm.setFieldValues({ fieldId: 39 }, "Creating")
    }
    else {
        LFForm.setFieldValues({ fieldId: 39 }, "")
    }
}

LFForm.subscribe('fieldChange', () => getRequirements(req_OutlinePackageA_fieldId, 'OutlinePackageA'), { fieldId: req_OutlinePackageA_fieldId });
LFForm.subscribe('fieldChange', () => getRequirements(req_TestReports_fieldId, 'TestReports'), { fieldId: req_TestReports_fieldId });
LFForm.subscribe('fieldChange', () => getRequirements(req_InstructBooks_fieldId, 'InstructBooks'), { fieldId: req_InstructBooks_fieldId });
LFForm.subscribe('fieldChange', () => getRequirements(req_SparePLU_fieldId, 'SparePLU'), { fieldId: req_SparePLU_fieldId });
LFForm.subscribe('fieldChange', () => getRequirements(req_SolidWorks_fieldId, 'SolidWorks'), { fieldId: req_SolidWorks_fieldId });
LFForm.subscribe('fieldChange', () => getRequirements(req_Other_fieldId, 'Other'), { fieldId: req_Other_fieldId });

LFForm.subscribe('fieldChange', () => checkForModifications(), { fieldId: 4 })
LFForm.subscribe('fieldChange', () => checkForModifications(), { fieldId: 5 })
LFForm.subscribe('fieldChange', () => checkForModifications(), { fieldId: 6 })

function arraysEqualUnordered(arr1, arr2) {
    if (arr1.length !== arr2.length) return false;
    const sorted1 = [...arr1].sort();
    const sorted2 = [...arr2].sort();
    return sorted1.every((val, index) => val === sorted2[index]);
}

LFForm.onFormSubmission(function () {
    if (!validateDesignFreezeExists()) {
        return { error: "The design has been frozen. You can no longer submit design review/freeze request(s)." };
    }
    if (!validateDMI()) {
        return { error: "You must use the SO Number/Quote with letter for DMI. Eg: 25-12345/WQ123456. Please check your input." };
    }

    if (!validatePrototype()) {
        return { error: "You must use the SO Number with letter for PROTOTYPE. Eg: 25-12345A. Please check your input." };
    }
    if (!validateDesignFreeze()) {
        return { error: "The SO Number must have AT LEAST ONE design review to be able to submit the design freeze." };
    }
});

function validatePrototype() {
    var task = LFForm.getFieldValues({ fieldId: for_fieldId })
    var soNumber = LFForm.getFieldValues({ fieldId: soNumber_fieldId })

    var soNumberWithLetterPattern = /^\d{2}-\d{5}[A-Z]$/;

    if (task.value.includes("Design") && !soNumberWithLetterPattern.test(soNumber)) {
        return false;
    }

    return true;
}

function validateDesignFreeze() {
    var task = LFForm.getFieldValues({ fieldId: for_fieldId })
    try {
        var designReviewRevisions = LFForm.getFieldValues({ fieldId: 68 })

        if (task.value === "Design Freeze" && designReviewRevisions.length <= 0) {
            return false;
        }

        return true;
    }
    catch (error) {
        if (task.value === "Design Freeze") {
            return false;
        }
        else return true;
    }
}

function validateDesignFreezeExists() {
    try {
        var task = LFForm.getFieldValues({ fieldId: for_fieldId })
        var designReviewTaskTypes = LFForm.getFieldValues({ fieldId: 67 })

        console.log(designReviewTaskTypes)

        if ((task.value === "Design Freeze" || task.value === "Design Review")
            && designReviewTaskTypes.includes("Design Freeze")) {
            return false;
        }
        return true;
    }
    catch (error) {
        return true;
    }
}

function validateDMI() {
    var task = LFForm.getFieldValues({ fieldId: for_fieldId })
    var soNumber = LFForm.getFieldValues({ fieldId: soNumber_fieldId })

    var soNumberTrimPattern = /^\d{2}-\d{5}$/;

    if (!task.value.includes("Design") && !soNumberTrimPattern.test(soNumber)) {
        return false;
    }

    return true;
}

LFForm.onFieldChange(() => {
    var task = LFForm.getFieldValues({ fieldId: for_fieldId })
    switch (task.value) {
        case "Approval":
        case "Record":
        case "Final As-Built":
            LFForm.setFieldValues({ fieldId: 78 }, { value: "DMI" })
            LFForm.setFieldValues({ fieldId: 39 }, "Creating")
            break;
        case "Design Review":
        case "Design Freeze":
            LFForm.setFieldValues({ fieldId: 78 }, { value: "Prototype" })
            if (task.value.includes("Freeze"))
                LFForm.setFieldValues({ fieldId: 39 }, "Creating")
            break;
    }
    LFForm.setFieldValues({ fieldId: 4 }, { value: [], otherChoiceValue: "" })
}, { fieldId: for_fieldId });
0 0
replied on November 10

Could you try changing your onLookupDone on line 63 to an onFieldChange watching the last of the fields filled by the lookup? You mention inconsistency and that is the one thing that stands out the most. onLookupDone doesn't guarantee a field value when filling form fields.

0 0
replied on November 10

@████████ the info can be null (rows not found) because the I want to allow the data to be loaded from what user input last time. If their request is rejected/cancelled/completed, the row will not be there to bind data.

I had to use JavaScript because the form data cannot be bound after the initial submission. The data needs to be the latest one since it might be modified from another system.

If I need to test them field by field to figure out what field is giving problem, how should I test them?

P/S: We got this to work again after restarting the server and the Forms Routing Service after a maintenance though. Also we tested this code on the testing instance of LF and it worked there. This error happened only on the production environment.

0 0
replied on November 11

I'm glad you got it working, I was mostly referring to onLookupDone potentially not being the right event to listen to when parsing form data. Not sure if you are reading fields being set by the lookup or not.

As for testing, I would recommend using logging and the browser devtools to step through your functions.

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.