Correct way to unsubscribe from request.$context.events$ in crt.HandleViewModelInitRequest?

Hi Community,

I’m on Creatio 8.3.2 (Freedom UI) and I’m trying to set the first tab as the default on every page init, because the designer option under Tabs (“Default tab”) isn’t working in my case, so I’m doing it in code.

What I’m doing

I subscribe to the page model events inside crt.HandleViewModelInitRequest and wait for finish-load-model-attributes, then set the tab index to 0:

{
  request: "crt.HandleViewModelInitRequest",
  handler: async (request, next) => {
    await next?.handle(request);
 
    request.$context.events$.subscribe(async (evt) => {
      const modelMode = await request.$context.getPrimaryModelMode();
 
      if (evt?.type === "finish-load-model-attributes") {
        if (modelMode === "update") {
          request.$context.Tabs_SelectedTabIndex_Profile = 0;
        }
        if (modelMode === "create") {
          request.$context.Tabs_SelectedTabIndex_Profile = 0;
        }
      }
    });
  }
}

The problem

This event is emitted more than once (e.g., when another list/detail inside a tab finishes loading later), so my code keeps re-triggering and forces the UI back to tab 0 even after the user already switched tabs.

Unsubscribe attempt (doesn’t work)

I tried the pattern I saw in a comment on the CustomerFX article about waiting for the model to be loaded (store the returned subscription and call unsubscribe() when the needed payload arrives):customerfx

const sub = request.$context.events$.subscribe(async (evt) => {
  if (evt?.type === "finish-load-model-attributes" && evt?.payload?.SomeAttribute) {
    sub.unsubscribe();
  }
});

But in my case (8.3.2 Freedom UI) this doesn’t seem to work at all.

Questions

  • What is the correct syntax / pattern to unsubscribe from request.$context.events$ subscriptions on Freedom UI pages (8.3.2)?
  • Does events$.subscribe(...) always return an object that supports unsubscribe() in Freedom UI, or is there a different disposal mechanism?
  • Is there a recommended “run once when page is really ready” event/request that avoids finish-load-model-attributes firing multiple times?

If anyone has a working example for 8.3.x (especially for “run once” behavior or proper unsubscribe), I’d really appreciate it.

Like 1

Like

2 comments

Hello,
Currently, there are some issues with the default tab logic, and our R&D team is working on a global solution for it. As for now, the recommended approach is the following:
The current mechanism relies on saving the selected tab through the page configuration (viewConfig), which may lead to conflicts and incorrect behavior.
To ensure stable operation, the default tab must be controlled at the ViewModel level.
As a workaround for now, you can apply the following steps:
- Use the SelectedTabIndex property instead of SelectedTab. 

- Store the tab index in a dedicated ViewModel attribute.

- Disable saving the selected tab in the profile to prevent conflicts. (DisableSaveToProfileSelectedTabIndex)


 

Dmytro Vovchenko,

Thanks for the guidance, that clarifies the ViewModel‑side approach a lot.

Quick follow‑up: could you also please point me to the correct way to unsubscribe from request.$context.events$ in Freedom UI (8.3.2)?

Right now I’m doing something like this inside crt.HandleViewModelInitRequest:

{ 
  request: "crt.HandleViewModelInitRequest",
  handler: async (request, next) => {
    await next?.handle(request);
 
    const sub = request.$context.events$.subscribe(async (evt) => {
      const modelMode = await request.$context.getPrimaryModelMode();
 
      if (evt?.type === "finish-load-model-attributes") {
        if (modelMode === "update" || modelMode === "create") {
          request.$context.Tabs_SelectedTabIndex_Profile = 0;
 
          // I want this to run only once, then stop listening
          sub.unsubscribe?.();
        }
      }
    });
  }
}

Any small code snippet or hint for 8.3.x specifically would be really helpful.

 

Show all comments