[SalesForce] Salesforce lightning component – Close original sub tab and open new Sub tab

I'm trying to accomplish the following:
I have quick action that fires lightning component.
This quick action is under opportunity and what i'm trying to achieve is the following:
Once the button is pressed – close the current sub tab (opportunity sub tab) and open new sub tab which contains vf page.

Everything works as expected, but i'm not able to set the new sub tab label (for now – the label shows the vf page name ..).

This is my code:

var workspaceAPI = component.find("workspace");

                workspaceAPI.isConsoleNavigation().then(function(consoleResponse) {
                    if (consoleResponse) {    
                        // Save current tab info
                        workspaceAPI.getFocusedTabInfo().then(function(tabResponse) {
                            var closeTabId = tabResponse.tabId;
                            var closeTitle = tabResponse.title;

                            var parentTabId = tabResponse.parentTabId;
                            var isSubtab = tabResponse.isSubtab;
                            console.log("Is Sub: ",isSubtab," ParentId: ",parentTabId);

                            // Open Visualforce Page in a new tab
                            if (isSubtab) { 
                                workspaceAPI.openSubtab({ 
                                    parentTabId: parentTabId,
                                    url: vfURL,
                                    focus: true
                                }).then(function(openSubResponse) {
                                    console.log("New SubTab Label: ", consoleLabel);
                                    console.log("New SubTab Id: ", openSubResponse);
                                    workspaceAPI.setTabLabel({
                                        tabId: openSubResponse,
                                        label: "new sub tab label"
                                    })
                                })
                                .catch(function(error) {
                                    console.log(error);
                                    component.set("v.errorMessage", error);
                                }); 
                            } else {
                                workspaceAPI.openTab({
                                    url: vfURL,
                                    focus: true
                                }).then(function(openParResponse) {
                                    console.log("New ParentTab Id: ", openParResponse);
                                    workspaceAPI.setTabLabel({
                                        tabId: openParResponse,
                                        label: "new sub tab label"
                                    })
                                })
                                .catch(function(error) {
                                    console.log(error);
                                    component.set("v.errorMessage", error);
                                });                        
                            } 
                            if (tabResponse.closeable && !tabResponse.pinned) {
                                workspaceAPI.closeTab({ 
                                    tabId: closeTabId
                                }).then(function(closeResponse) {
                                    console.log("Closed: ", closeTitle);
                                })
                                .catch(function(error) {
                                    component.set("v.errorMessage", error);
                                });
                            }
                        });                

When i'm taking out the functionality which closes the current sub tab – the new sub tab label is populated as I defined.

Any ideas ?

Best Answer

That is because javascript is basically single threaded processing, and all the async processing is just handled by browser after the main thread is completed - again in single thread only. In your case workpaceAPI is async processing but as you are calling both openSubtab and closeTab at same time, closeTab is overriding the callback of openSubtab.

You should invoke closeTab in callback of openSubtab - logically you should close a tab AFTER opening other.

CONTROLLER:

workspaceAPI.getFocusedTabInfo().then(function(tabResponse) {
        var closeTabId = tabResponse.tabId;
        var closeTitle = tabResponse.title;

        var parentTabId = tabResponse.parentTabId;
        var isSubtab = tabResponse.isSubtab;
        console.log("Is Sub: ",isSubtab," ParentId: ",parentTabId);

        // Open Visualforce Page in a new tab
        if (isSubtab) { 
            workspaceAPI.openSubtab({ 
                parentTabId: parentTabId,
                url: '/apex/poc',
                focus: true
            }).then(function(openSubResponse) {
                console.log("New SubTab Label: ", 'consoleLabel');
                console.log("New SubTab Id: ", openSubResponse);
                workspaceAPI.setTabLabel({
                    tabId: openSubResponse,
                    label: "new sub tab label"
                });
                helper.closeTab(component, tabResponse, closeTabId);
            })
            .catch(function(error) {
                console.error("ERROR => ",error);
            }); 
        }
    });

HELPER:

closeTab : function(component, tabResponse, closeTabId) {
    var workspaceAPI = component.find("workspace");
    if (tabResponse.closeable && !tabResponse.pinned) {
        workspaceAPI.closeTab({ 
            tabId: closeTabId
        }).then(function(closeResponse) {
            console.log("Closed: ", closeTitle);
        })
        .catch(function(error) {
            console.error("ERROR => ",error);
        });
    }
},