How to unbind 'PreferenceScopeTabBar'

Hello:
I wanna delete User Tab on Preference Tab Menu.
So I tried to unbind PreferenceTabBar and rebind edited preference Tabbar which has no ‘addUserTab.’ But it keeps showing error like unbinding Preference TabBar is not possible.

Here is the list what I wanna know.
1st, is it possible to edit Preference Tab Siblings?
2nd, if 1st is, is unbinding Preference Tab not a good way?

[Source Code - unbinding]

export default new ContainerModule((bind, unbind, isBound, rebind) => {
unbind(PreferencesWidget);
bind(PreferencesWidget)
    .toDynamicValue(({ container }) => createPreferencesWidgetContainer(container).get(PreferencesWidget))
    .inSingletonScope();
bind(WidgetFactory).toDynamicValue(({ container }) => ({
    id: PreferencesWidget.ID,
    createWidget: () => container.get(PreferencesWidget)
})).inSingletonScope();
});

function createPreferencesWidgetContainer(parent: interfaces.Container): Container {
const child = createTreeContainer(parent);
child.bind(PreferenceTreeModel).toSelf();
child.rebind(TreeModel).toService(PreferenceTreeModel);
child.unbind(TreeWidget);
child.bind(PreferencesTreeWidget).toSelf();
child.rebind(TreeProps).toConstantValue({ ...defaultTreeProps, search: false });
child.bind(PreferencesEditorWidget).toSelf();

child.bind(PreferencesSearchbarWidget).toSelf();
child.rebind(PreferencesScopeTabBar).toService(EditedPreferencesScopeTabBar);

[Source Code - disable ‘addUserTab()’]
@injectable()

export class EditedPreferencesScopeTabBar extends PreferencesScopeTabBar {

    protected setupInitialDisplay(): void {

        //this.addUsertab();

        if (this.workspaceService.workspace) {

            this.addWorkspaceTab(this.workspaceService.workspace);

        }

        this.addOrUpdateFolderTab();

    }

}

Hi @mufassa

The reason your application throws an error is that PreferencesScopeTabBar is rebound, without ever being bound normally. To fix this, you need two changes in your custom container module: first off, rebinding the PreferencesWidget, like you already did:

rebind(PreferencesWidget)
        .toDynamicValue(({ container }) => createCustomPreferencesWidgetContainer(container).get(PreferencesWidget))
        .inSingletonScope();

And then create a createCustomPreferencesWidgetContainer function that is exactly the same as this method

In there you have to change:

child.bind(PreferencesScopeTabBar).toSelf();

to:

child.bind(EditedPreferencesScopeTabBar).toSelf();
child.bind(PreferencesScopeTabBar).to(EditedPreferencesScopeTabBar);

First of all, it works!

Thanks a lot!

I only changed

child.bind(PreferencesScopeTabBar).toSelf();

to

child.bind(EditedPreferencesScopeTabBar).toSelf();
child.bind(PreferencesScopeTabBar).to(EditedPreferencesScopeTabBar);

as you exactly said.

But I’m still curious why binding ‘EditedPreferencesScopeTabBar’ is not possible after ‘PreferencesScopeTabBar’ unbinded. And error shows exact same context ‘Could not unbind serviceIdentifier: PreferencesScopeTabBar.’

In the code that I showed you on previous post, ‘PreferencesTreeWidget’ is binded after ‘TreeWidget’ unbinded.

Is there a difference between those unbinding/binding?

[Comparing binding ‘EditedPreferencesScopeTabBar’ after ‘PreferencesScopeTabBar’ unbinded and binding ‘PreferencesTreeWidget’ after ‘TreeWidget’ unbinded]

child.bind(PreferenceTreeModel).toSelf();

    child.rebind(TreeModel).toService(PreferenceTreeModel);

    //Original Code [binding 'PreferencesTreeWidget' after 'TreeWidget' unbinded]
    child.unbind(TreeWidget);

    child.bind(PreferencesTreeWidget).toSelf();

    child.rebind(TreeProps).toConstantValue({ ...defaultTreeProps, search: false });

    child.bind(PreferencesEditorWidget).toSelf();

    child.bind(PreferencesSearchbarWidget).toSelf();

    //Edited but not working [binding 'EditedPreferencesScopeTabBar' after 'PreferencesScopeTabBar' binded]
    child.unbind(PreferencesScopeTabBar);

    child.bind(EditedPreferencesScopeTabBar).toSelf();

    child.bind(PreferencesWidget).toSelf();

Thank you for your kindness

Well, inversify won’t be able to unbind what is never bound. Before calling:

child.unbind(PreferencesScopeTabBar);

You would have to first bind it:

child.bind(PreferencesScopeTabBar).toSelf();

But that never happens in your case. That’s the source of the error. You don’t need to unbind it, if it’s never bound. This is probably a bit confusing, since most services/widgets/whatever in Theia are bound globally on application startup. But in this case, we create a local child container that binds the PreferencesScopeTabBar, which is never bound globally. So no need to unbind it in the first place.

Thanks again for your kindness.

Finally, trully I understood.

I was confused, as you guessed. Because in node-modules’ preferences, there is ‘PreferencesScopeTabBar’ binded so that I thought I could unbind it in my custom extension code.

node-module/@theia/preferences/src/views/preference-widget-bindings.ts:
function createPreferencesWidgetContainer(parent: interfaces.Container): Container {

    const child = createTreeContainer(parent);

    child.bind(PreferenceTreeModel).toSelf();

    child.rebind(TreeModel).toService(PreferenceTreeModel);

    child.unbind(TreeWidget);

    child.bind(PreferencesTreeWidget).toSelf();

    child.rebind(TreeProps).toConstantValue({ ...defaultTreeProps, search: false });

    child.bind(PreferencesEditorWidget).toSelf();

    child.bind(PreferencesSearchbarWidget).toSelf();

    child.bind(PreferencesScopeTabBar).toSelf();

    child.bind(PreferencesWidget).toSelf();

Thank you again.

I wish luck for you.