Attached() not firing on click - SOLVED

I am trying to display a set of stored results from aurelia-store when a user clicks on the Search link.

In order to make sure the document is loaded first, I have done the following:

constructor()
{
this.loadResults = e => {
            console.log('loaded', this.state.searchObj);
            this.activate();
        };
}

    attached()
    {
        document.addEventListener('aurelia-composed', () => {
            this.loadResults();
        });
        
    }

then further down, I am doing the following to get the document and load the results:

var eGridDiv = document.querySelector('#resultsGrid');
        var newDiv;

        //console.log('document', document);
        //console.log('egriddiv', eGridDiv);

        if (typeof(eGridDiv) == undefined || eGridDiv == null)
        {
            newDiv = document.createElement('div');
            newDiv.id = 'resultsGrid';
            newDiv.classList.add('ag-theme-alpine');
            newDiv.style.height = '300px';
            newDiv.style.width = '1200px';

            var bodyDiv = document.getElementById('pagecontent');

            console.log('bodyDiv', bodyDiv);
            
            //bodyDiv.appendChild(newDiv);

            document.body.appendChild(newDiv);

            eGridDiv = document.querySelector('#resultsGrid');
            console.log('2 egriddiv', eGridDiv);

            this.resultsGrid = new ag.Grid(eGridDiv, this.resultsGridOptions);

            if (typeof(this.state) != undefined && this.state != null)
            {
                this.results = this.state.searchObj.results;    
            }

            this.resultsGridOptions.api.setRowData(this.state.searchObj.results);
            this.resultsGridOptions.api.refreshCells();
        }
        else
        {
            this.resultsGrid = new ag.Grid(eGridDiv, this.resultsGridOptions);
            this.resultsGridOptions.api.setRowData(this.state.searchObj.results);
            this.resultsGridOptions.api.refreshCells();
        }

The attached() fires the first time the page is loaded, but when I click away from it to a view of a customer, and then click the link again, it does not fire attached(), which means the document is not loaded, and then it creates the new div, and then attaches it right to the body. Which means that the search form is underneath the search results.

What am I missing in this?

Thanks

Are you using a router? Viewmodels for navigationInstructions get reused by default. What you might be looking for is activate instead of attached. Moreover activate will wait for any promise returned. Moreover you dont need to wait for the event as by the time attached is called, Aurelia definitely is ready and composed. So just remove that part

That is interesting. I did not know that.

Maybe you can help me think this through.

If I just run activate to load the previous search results and attach them to the document using appendchild, it doesn’t load properly. The results are layered on top of the form because it appears that the view model doesn’t appear to be loaded?

How can I make sure the viewmodel is loaded before trying to attach the results?

I’ve got the placeholder for the results attached to the viewmodel like this:

<div id="pagecontent" class="body pagecontent">
<!--some stuff-->
<div id="resultsDiv" style="align-content: center;" width="95%">
            <div id="resultsGrid" style="font-size: 11px; height: 300px; width: 1200px;"
                class="ag-theme-alpine">
            </div>
        </div>

Where I get my div for attaching the results:

var eGridDiv = document.querySelector('#resultsGrid');
        var newDiv;

        //console.log('document', document);
        //console.log('egriddiv', eGridDiv);

        if (typeof(eGridDiv) == undefined || eGridDiv == null)
        {
            newDiv = document.createElement('div');
            newDiv.id = 'resultsGrid';
            newDiv.classList.add('ag-theme-alpine');
            newDiv.style.height = '300px';
            newDiv.style.width = '1200px';

            var bodyDiv = document.getElementById('resultsDiv');

            console.log('bodyDiv', bodyDiv);
            
            bodyDiv.appendChild(newDiv);

The problem I am running into is that even bind() is not called again when I click back to that viewmodel, so when I log the document, it’s the viewmodel for Customer and not for Search.

How can I get the viewmodel to finish loading and then run the loading of results?

I managed to answer my own question.

By using EventAggregator and Router Navigation, I was able to get things to load properly.

Here is my code for future reference:

    attached()
    {
        this.ea.publish('router:navigation:complete', this.state.searchObj.results);

        this.ea.subscribe('router:navigation:complete', event => {
            if (typeof(this.state.searchObj.results) != undefined && 
            this.state.searchObj.results != null)
            {
                this.results = this.state.searchObj.results;
                this.wltype = this.state.searchObj.searchRecord.wltype;
                this.wl_total = this.formatter.format(this.state.searchObj.searchRecord.wl_total);

                this.initResultsGrid();
            }
        });   
    }