Cannot override fetchRecords action on the SmartView

I’m trying to override the default behavior of fetching records on the SmartView, but it doesn’t seem to work as expected.

If I add some sort of condition in the filter and click ‘Apply filters’, then I see no log message.
Looks like the base method from the SmartViewMixin is still triggered.
What is the correct way to override the action?

// smart-view.js
export default Component.extend(SmartViewMixin, {
    init(...args) {
        this._super(...args);
        ...
    }

    actions: {
        fetchRecords() {
            console.log('fetching records...');
            ...
        }
    }
// smart-view.hbs
{{table/table-frame
    columns=@columns
    columnsVisible=@columnsVisible
    collection=@collection
    viewList=@viewList
    records=@records
    sortBy=(action "sortBy")
    sortedField=@sortedField
    currentPage=@currentPage
    numberOfPages=@numberOfPages
    recordsCount=@recordsCount
    isLoading=@isLoading
    fetchRecords=@fetchRecords
    updateColumn=@updateColumn
}}

{{table/table-footer
    collection=@collection
    viewList=@viewList
    records=@records
    currentPage=@currentPage
    numberOfPages=@numberOfPages
    recordsCount=@recordsCount
    isLoading=@isLoading
    fetchRecords=@fetchRecords
}}

Expected behavior

Custom overriding method is triggered.

Actual behavior

Default action is triggered.

The action fetchRecords is actually calling the function fetchRecords that is passed as an argument to the smart view.

I did not check, but you might consider changing the value of this.fetchRecords inside the init function in order to override this behavior.

    init(...args) {
        this._super(...args);
        this.fetchRecords = this.customFetchRecords.bind(this)
    },

    customFetchRecords(){
      console.log('fetching records')
    }

@GuillaumeGautreau Thanks! I will try it out and will get back to you.

@GuillaumeGautreau unfortunately it did not help

Ok, after looking at the code more precisely:

  • The smart view gets instanciated with the property record that is passed as an argument to the composant. So the smart view itself does not have access to the request that is made beforehand, in order to get the list of records
  • The parameter fetchRecords is actually useful if you wan to reload the data, after a modification for instance.

So I don’t see how you can replace the current behavior by your own.

Hello @Vasilii,

As the way to retrieve records cannot be easily changed in the smart view, is it possible for you to change the code in the backend, by overriding the behavior of the corresponding route?

@GuillaumeGautreau sadly enough, it is impossible.

We are sending values from custom controls on the Smart View, that determine records being fetched from the backend.

If I understand it well, the first load of records is correct with displaying your smart view, but then your users make actions on your smart view, that alter the list of records that must be displayed? Such as filters or search etc.

Am I right?

@GuillaumeGautreau yes, you are right.

In the component we had an action responsible for the data fetch:

smart-table.js
export default Component.extend(SmartViewMixin, {

actions: {
fetchData() { }
}

});

Inside the fechData() method we are collecting parameters from the filters and custom controls, combing them, send query to back-end and set records with the response.

In the template we are assigning fetchRecords with the custom action from our component:

smart-table.hbs
{{table/table-frame
columns=@columns
columnsVisible=@columnsVisible
collection=@collection
viewList=@viewList
records=@records
sortBy=(action “sortBy”)
sortedField=@sortedField
currentPage=@currentPage
numberOfPages=@numberOfPages
recordsCount=@recordsCount
isLoading=@isLoading
fetchRecords=(action “fetchData”)
updateColumn=@updateColumn
}}
{{table/table-footer
collection=@collection
viewList=@viewList
records=@records
currentPage=@currentPage
numberOfPages=@numberOfPages
recordsCount=@recordsCount
isLoading=@isLoading
fetchRecords=(action “fetchData”)
}}

Hey @Vasilii,

Just one advise, don’t use action you can simply use this.fetchData :wink:

For your problem, I don’t see where you have an issue. You have your fetchData, so you can do whatever you want in your fetchData function :thinking:

@vince you are absolutely right, we do whatever we want in our code.

The issue starts, when the default behavior is invoked.
When any condition is added to the filter and button ‘Apply filters’ is clicked I expect our action fetchData to be triggered (where filter values and custom fields values are combined prior to sending the request). Instead, default fetchRecords method is triggered and only filter values are sent in request and values from custom fields are ignored.

Hi @Vasilii,

Are you saying that using this:

smart-table.hbs
{{table/table-frame

fetchRecords=this.fetchData

}}
{{table/table-footer

fetchRecords=this.fetchData

}}

Your “fetchData” function is not called and the default one is called instead?
(You said yes to Vince but your code extract contains an action.)

Regards

@Sliman_Medini I said ‘yes’ in regards to:

You have your fetchData, so you can do whatever you want in your fetchData function :thinking:

I’ve tried code abstract proposed by @vince, but still default function for fetching records is called.

@Vasilii, sadly the filter button is outside the smart view so you can’t control what is happening on it :thinking:.

I may have an idea, could you try something like that:

<div {{did-update this.fetchData @filters}}/>

This should certainly send 2 requests, the first one that you don’t want should be canceled and the second one should be the one modified as you wished

@GuillaumeGautreau @vince @Sliman_Medini hi, again

Deeper debugging sessions with attempts to apply your proposals blossomed into interesting results.
Turns out the core issue was in a totally different place.

To merge filters and custom control values we are tracking changes to the filters object via filters button.
Previously it had identifier id='c-beta-filter-button', now it turned into a class class='c-beta-filter-button'. I’ve fixed the selector and seems to be working as before.

Anyways, thanks for help :clap:t3: :clap:t3: :clap:t3:

2 Likes