function getLocalConfigValueFromModelValue()

in ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js [969:1071]


        function getLocalConfigValueFromModelValue(key, value) {
            if (!specEditor.defined(value) || value === null) {
                return value;
            }

            if (value.hasOwnProperty(DSL_ENTITY_SPEC)) {
                let wrapper = {};
                wrapper[REPLACED_DSL_ENTITYSPEC] = value[DSL_ENTITY_SPEC];
                return wrapper;
            }
            if (value instanceof Dsl) {
                return value.toString();
            }

            let definition = scope.model.miscData.get('config').find(config => config.name === key);
            if (!definition) {
                definition = {};
                scope.getConfigWidgetMode(definition, value)
            } else {
                if (!definition.widgetMode) scope.getConfigWidgetMode(definition, value);
            }

            // if json mode, then just stringify
            if (scope.state.config.codeModeActive[key]) {
                if (scope.state.config.codeModeError[key]) {
                    // errors don't get stringified because model value was not parsed
                    return value;
                }
                // if current local value gives same result then don't change it
                // (don't interrupt user's flow, and respect their spacing, at least until
                // they click away; ultimately we would like access to the parse tree,
                // so we could take the text as entered exactly (maybe stripping initial whitespace),
                // also supporting yaml and comments, but that is a bigger task!)
                if (scope.config && typeof scope.config[key] === 'string') {
                    try {
                        if (JSON.stringify(parseYamlOrJson(scope.config[key])) === JSON.stringify(value)) {
                            return scope.config[key];
                        }
                    } catch (ignoredError) {
                        $log.debug("Couldn't handle entered JSON", scope.config[key], ignoredError);
                    }
                }
                // otherwise pretty print it, so they get decent multiline on first load and
                // if they click off the entity then back on to the entity and this field
                // (we'd like to respect what they actually typed but that needs the parse tree, as above)
                return toCode(value, true);
            }

            // else treat as value, with array/map special

            try {
                if (definition.widgetMode === 'array' || definition.widgetMode === 'array-manual') {
                    if (Array.isArray(value)) {
                        return value.map(item => {
                            if (item instanceof Dsl) {
                                return item.toString();
                            } else if (item instanceof Array || item instanceof Object || typeof item === 'object') {
                                throw 'not simple json in array';
                            } else {
                                return item;
                            }
                        });
                    }
                    // fall through to return toString below
                } else if (definition.widgetMode === 'map' || definition.widgetMode === 'map-manual') {
                    if (typeof value === "object") {
                        let object = {};
                        for (let keyObject in value) {
                            if (value[keyObject] instanceof Dsl) {
                                object[keyObject] = value[keyObject].toString();
                            } else if (value[keyObject] instanceof Array || value[keyObject] instanceof Object || typeof value[keyObject] === 'object') {
                                throw 'not simple json in map';
                            } else {
                                object[keyObject] = value[keyObject];
                            }
                        }
                        return object;
                    }
                    // fall through to return toString below
                } else if ((value instanceof Object || value instanceof Array || typeof value === 'object') && !(value instanceof Dsl)) {
                    throw 'must use code editor for array/object';
                }
            } catch (hasComplexJson) {
                // any map/array with complex json inside, or other value of complex json,
                // will force the code editor
                // (previously we did stringify on entries then tried to parse, but that was inconsistent)
                console.log("Forcing code mode on ", key, "=", value, "because", hasComplexJson);

                scope.state.config.codeModeActive[key] = true;
                // and the widget mode updated to be 'manual'
                scope.getConfigWidgetMode(definition, value);
                // and rerun this method so we get it prettified if appropriate
                return getLocalConfigValueFromModelValue(key, value);
            }

            // if boolean, return as primitive type
            if (typeof value === 'boolean') {
                return value;
            }

            // all other primitives treat as string (as they will get a string-based widget)
            return "" + value;
        }