eclipsesource / eclipsesource/jsonforms-vue-seed

Vue Error: TypeError: Cannot read properties of undefined (reading 'code')

Open
#28 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Vue
Stars
49
Forks
32
PR merge metrics
No merged PRs in 30d

Description

Hi I got the error while using the package of jsonforms with vue2 seed. Also I've used vue2 with laravel 5.8.

Encountering a **TypeError: Cannot read properties of undefined (reading 'code')** error in Vue 2 application using JSONForms when processing dynamic form data.

Below are my package.json file:
`{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development NODE_OPTIONS='--openssl-legacy-provider' node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development NODE_OPTIONS='--openssl-legacy-provider' node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production NODE_OPTIONS='--openssl-legacy-provider' node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"storybook": "start-storybook -p 9000"
},
"devDependencies": {
"axios": "^0.19",
"bootstrap": "^4.1.0",
"cross-env": "^5.1",
"jquery": "^3.2",
"laravel-mix": "^4.0.7",
"lodash": "^4.17.13",
"popper.js": "^1.12",
"resolve-url-loader": "^2.3.1",
"sass": "^1.15.2",
"sass-loader": "^7.1.0",
"vue": "^2.6.14",
"vue-template-compiler": "^2.6.14"
},
"dependencies": {
"@jsonforms/core": "^2.4.0",
"@jsonforms/vue2": "^2.4.0",
"@jsonforms/vue2-vanilla": "^2.4.0",
"@vue/composition-api": "^1.7.2",
"ajv": "^6.12.6",
"ajv-formats": "^1.5.1",
"core-js": "^3.6.5",
"regenerator-runtime": "^0.14.1",
"tslib": "^2.8.1",
"uuid": "^9.0.0"
}
}
`
Below my component code:
`



Loading form schema...







{{ tab.label }} 1








All Fields Tab








No form available. Check console for errors.





Required Fields Tab




Required fields view is not available. Showing all fields instead.









No form available. Check console for errors.






import { generateDefaultUISchema } from '@jsonforms/core';
import { JsonForms } from '@jsonforms/vue2';
import { cloneDeep } from "lodash";
import { vanillaRenderers } from '@jsonforms/vue2-vanilla';
import Ajv from 'ajv';
import addFormats from "ajv-formats";
import { entry as arrayListEntry } from './Custom/ArrayList.vue';

export default {
name: 'JsonFormsComponent',
components: {
JsonForms,
},
data() {
return {
data: {},
ID_SUFFIX: "/Augmented",
schemaValidator: null,
renderers: [],
uiSchema: null,
requiredUiSchema: null,
activeTab: 'all',
tabs: [
{ id: 'all', label: 'All Fields' },
{ id: 'required', label: 'Required Fields' }
],
loadedSchema: null
};
},

methods: {
cleanUpSchemaForPresentation(schema) {
if (!schema || typeof schema !== 'object') {
return schema;
}
// For simplified schemas, we don't need aggressive cleaning
// Just ensure we have a valid schema structure
const clonedSchema = cloneDeep(schema);

// Only clean problematic properties if they exist
if (clonedSchema.allOf) {
delete clonedSchema.allOf;
}
if (clonedSchema.anyOf) {
delete clonedSchema.anyOf;
}
if (clonedSchema.oneOf) {
delete clonedSchema.oneOf;
}

// Ensure we have a valid ID
if (!clonedSchema.$id) {
clonedSchema.$id = this.generateUuid();
}

return clonedSchema;
},

generateUISchema(schema) {
return generateDefaultUISchema(this.cleanUpSchemaForPresentation(schema));
},

generateUuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},

generateRequiredUISchema(schema) {
try {
const clonedSchema = cloneDeep(schema);
const requiredSchema = this.filterRequiredFields(clonedSchema);
const uiSchema = generateDefaultUISchema(requiredSchema);
return uiSchema;
} catch (error) {
console.error('Error generating required UI schema:', error);
// Fallback to main UI schema if there's an error
return this.uiSchema;
}
},

filterRequiredFields(schema) {
if (!schema || typeof schema !== 'object') {
return schema;
}

const filteredSchema = { ...schema };

if (schema.properties) {
const requiredProps = schema.required || [];
const filteredProperties = {};

Object.keys(schema.properties).forEach(propName => {
const prop = schema.properties[propName];
if (requiredProps.includes(propName) || this.hasRequiredFields(prop)) {
filteredProperties[propName] = this.filterRequiredFields(prop);
}
});

filteredSchema.properties = filteredProperties;
filteredSchema.required = requiredProps.filter(propName =>
filteredProperties.hasOwnProperty(propName)
);
}

return filteredSchema;
},

hasRequiredFields(schema) {
if (!schema || typeof schema !== 'object') {
return false;
}

if (schema.required && schema.required.length > 0) {
return true;
}

if (schema.properties) {
return Object.values(schema.properties).some(prop => this.hasRequiredFields(prop));
}

return false;
},

switchTab(tabId) {
this.activeTab = tabId;
},

initializeSchemaValidator() {
this.schemaValidator = new Ajv({
allErrors: true,
verbose: true,
strict: false,
validateSchema: false,
});
addFormats(this.schemaValidator);
},

initializeRenderers() {
// Try putting custom renderer at the end for higher priority
this.renderers = [...vanillaRenderers, arrayListEntry];
this.renderers = Object.freeze(this.renderers);
},

onChange(e) {
try {
// Ensure the event object is valid before accessing properties
if (e && typeof e === 'object' && e.data !== undefined) {
this.data = e.data;
} else {
console.warn('Invalid change event received:', e);
this.data = {};
}
} catch (error) {
console.error('Error in onChange handler:', error);
this.data = {};
}
},

loadHerbSchema() {
try {
// Try to load from the correct path first
let response = fetch('/storage/herb.json');
if (!response.ok) {
// Fallback to test schema if herb.json fails
throw new Error('HTTP error! status: '+response.status);
}
const schema = response.json();
return schema;
} catch (error) {
console.error('Error loading schema:', error);
}
},
getValidationErrors() {
if (!this.schemaValidator || !this.loadedSchema || !this.data) {
return [];
}

try {
this.schemaValidator.validate(this.loadedSchema, this.data);
return this.schemaValidator.errors || [];
} catch (error) {
console.error('Error getting validation errors:', error);
return [];
}
},

getRequiredFieldErrors() {
const errors = this.getValidationErrors();
return errors.filter(error => {
// Filter for errors that indicate missing required fields
return error.keyword === 'required' ||
(error.keyword === 'minLength' && error.params && error.params.limit === 0) ||
(error.keyword === 'minItems' && error.params && error.params.limit > 0);
});
}

},
mounted() {
this.initializeSchemaValidator();
this.initializeRenderers();

// Load schema from herb.json
this.loadedSchema = this.loadHerbSchema();

if (this.loadedSchema) {
try {
// Clean and prepare the schema
const cleanedSchema = this.cleanUpSchemaForPresentation(this.loadedSchema);

// Ensure the schema has properties
if (!cleanedSchema.properties || Object.keys(cleanedSchema.properties).length === 0) {
cleanedSchema.properties = {
fallback_message: {
type: 'string',
title: 'Schema Information',
description: 'The schema was loaded but contains no displayable properties',
readOnly: true
}
};
cleanedSchema.required = [];
}

// Generate UI schema
try {
this.uiSchema = this.generateUISchema(cleanedSchema);
} catch (error) {
console.error('Error generating UI schema:', error);
// Create a simple fallback UI schema
this.uiSchema = {
type: 'VerticalLayout',
elements: Object.keys(cleanedSchema.properties || {}).map(propName => ({
type: 'Control',
scope: `#/properties/${propName}`
}))
};
}

// Generate required UI schema
try {
this.requiredUiSchema = this.generateRequiredUISchema(cleanedSchema);
} catch (error) {
console.error('Error generating required UI schema:', error);
// Use main UI schema as fallback for required fields
this.requiredUiSchema = this.uiSchema;
}
} catch (error) {
console.error('Error generating schemas in mounted:', error);
}
} else {
console.error('Failed to load schema');
}
},
computed: {
effectiveSchema() {
// Use loaded schema from herb.json
const schema = this.loadedSchema;
return schema;
},

isSchemaReady() {
return this.loadedSchema
&& Object.keys(this.loadedSchema

).length > 0 && this.uiSchema;
},
requiredFieldsCount() {
const schema = this.loadedSchema;
if (!schema || !schema.properties) {
return 0;
}

let count = 0;
const errors = this.getValidationErrors();
count = errors.length;
return count;
}
},
};
`

**Requirements**
- I don't want to upgrade the packages version of vue, vue-template-compiler & laravel-mix.

**Please help me figure out this error.**

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.