I am trying to migrate an old golden-layout implementation in an Angular 16 application, to golden-layout-2. The previous implementation worked as expected.
The code to initialise the layout is like this:
// create the layout
this.goldenLayout = new GoldenLayout(this.el.nativeElement);
// add golden-layout event handlers
this.registerGoldenLayoutEventListeners();
// register all golden-layout components
this.glService.initialize(this.goldenLayout, this);
// Initialize the layout
const layoutConfig = LayoutConfig.fromResolved(this.goldenLayout.layoutConfig);
layoutConfig.root = layout.root;
this.goldenLayout.loadLayout(layoutConfig);
The initialize
function above is responsible for registering the components, it looks like this:
this.config.components.forEach((componentConfig: ComponentConfiguration) => {
const componentInitCallback = componentInitCallbackFactory.createComponentInitCallback(componentConfig.component);
goldenLayout.registerComponentFactoryFunction(componentConfig.componentType.toString(), componentInitCallback, false);
});
The createComponentInitCallback
function basically creates the inner Angular component.
There are no errors in the editor, it all looks like it should work, but is giving the error:
Error: Component type not registered and BindComponentEvent handler not assigned
It seems like the registerComponentFactoryFunction
should be registering the components, but I guess from the error message it is not for some reason..? Also I am not sure why it is complaining about BindComponentEvent handler not assigned
- bindComponentEvent handler is supposedly optional and I assumed it would not be required for "Embedding via Registration" (known as "classic registration", as described here: https://golden-layout.github.io/golden-layout/binding-components/)
Can someone provide some guidance? What am I missing?
Edit
As requested, here is a copy of the current config:
WidgetGoldenLayoutConfig = {
dimensions: {
dragProxyHeight: 300,
dragProxyWidth: 300,
},
settings: {
showPopoutIcon: false,
},
content: [
{
componentName: null,
componentState: undefined,
height: null,
id: null,
isClosable: true,
title: null,
type: 'column',
width: null,
content: [
{
componentName: null,
componentState: undefined,
height: null,
id: 'bfa378a3-2b9f-455d-b574-d0114daf3fa2',
isClosable: true,
title: null,
type: 'stack',
width: null,
content: [
componentName: 'golden-layout-widget',
componentType: 'golden-layout-widget',
componentState: {},
content: [],
height: null,
id: null,
isClosable: true,
title: 'My widget',
type: 'component',
width: null,
],
},
],
},
],
}
Edit 2
I checked why we were using toString() - it was basically to fix type issues in VSCode - it was highlighting componentType
and giving error "Argument of type 'JsonValue' is not assignable to parameter of type 'string'. Type 'number is not assignable to type 'string'".
So toString() was used to keep VSCode happy. The actual value of componentType (and previously componentName) are definitely string values.
Nevertheless, the changes I made since Daniel G's answer below have not made a difference, I still see the same error.
I am also seeing a second error after the first:
Cannot access rootItem before init
Again, this error is originating deep within golden-layout source, I have no idea why it occurs
Edit 3
Daniel G was right, problem was with componentType
- in some cases this property was missing, so I ensured it existed (and was a string) for all cases, and error has gone
It would be useful to see your config, but I find it interesting that your first parameter in the call to registerComponentFactoryFunction
is componentConfig.componentType.toString(). According to the documentation the componentType property of ComponetItemConfig must be of type string if it is registered with registerComponentFactoryFunction.
Is calling toString()
your way of converting a JsonValue to a string because it is initially some other type? If so, this may be way the registration is not found. Internally, components registered with classic methods are added to a map object so when they are retrieved the value in componentTypeName must be exactly the same as how it was registered.
In your config, I would make sure all the assignments to the componentType property are of string type and not some other type.