How to reset the state to original before querying SP List?

Hi,
I am working in a SP framework application that read, group and filter data from a list.

To do that I have a method in the app that get called from an onclick eventhandler.

This method contains just a switch to check what other method needs to be called. It looks like this:

private _handleRequest(request: string): void {
    switch (request) {
      case 'Customer':
      case 'Sales Manager':
        this.groupHandler(request);
        break;
      case 'Agreement Ended':
        this.getEnded();
        break;
      case 'Last Price Adjustment':
        this.getPassed();
        break;
      default:
        break;
    }
  }

The groupHandler method send a request to Sharepoint that fetchs all the data and then send the data to a ListView component which render it on the screen:

private groupHandler(group: string): void {
    group = group.replace(/ +/g, "");
    this.setState({
      groupByFields: [{
        name: group,
        order: GroupOrder.ascending
      }]
    });
  }
}

The getEnded and getPassed are almost similar, fetch data from sharepoint and filter the result before it is sended to the ListView component.

Each method update the state:

private getEnded(): void {
    
    this.props.provider.getEnded().then((listItems: IList[]) => {
      this.setState({
        listItems: listItems
      });
    });
  }

  private getPassed(): void {
    
    this.props.provider.getPassed().then((listItems: IList[]) => {
      this.setState({
        listItems: listItems
      });
    });
  }

ans it is initialize like this:

export interface IListState {
  listItems: IList[];
}

export default class AgreementDatabase extends React.Component<IAgreementDatabaseProps, IListState> {
  constructor(props: IAgreementDatabaseProps) {
    super(props);

    this.state = {
      listItems: []
    };
    

    this.groupHandler = this.groupHandler.bind(this);
    
  }

No the problem is, when I run the app and click on a link that call the groupHandler method the list get grouped without problem. The problem arise when, with the list grouped, I click on a link that call getEnded or getPassed method. In that case the list doesn’t reload before filtering the result. What I get is a grouped list with filtered results.
I post some images to better understanding.




How can I reset the state so every time I click on a button the app fetch the original state / values before applying filtering or grouping?

Best regards
Americo

A possible solution could be storing 2 arrays in your state

listItems: [],     //always contains the full unfiltered list
filteredListItems[], //initializes with the full unfiltered list

Your application should always use the filteredListItems to display the data.

Whenever you apply a filter, always filter the original listItems array and setState({ filteredListItems})

make sure you are only reading from the original listItems

1 Like

Thanks for your answer.
I think that I found the real problem and it has nothing to do with the state.
In the render method I am using ListView to render the list and in this component I am using the groupByFields property which automatically groups the results:

 <ListView
            items={this.state.listItems}
            viewFields={this._viewFields}
            groupByFields={this.state.groupByFields}
          />

The groups comes from a groupByFields state.
What I really need to do is find the way to deactivate this groupByfield property when I want to filter otherwise it doesn’t matter how I filter or manipulate the state, the result will be allways grouped.
Do you know a way to do that? or a way to add this property only when the groupHandler method gets called?
Best regards
Americo

In the render can you do something like:

render() {
  if(hasFilter) {
    return (
        <ListView
            items={this.state.listItems}
            viewFields={this._viewFields}
          />
    )
  }else{
    return (
         <ListView
            items={this.state.listItems}
            viewFields={this._viewFields}
            groupByFields={this.state.groupByFields}
          />
    )
  }
}
1 Like

thanks again for your help.
I still doing something wrong since the filter part is not getting called when I click on the button. This is what I have done by using your two tips:

{this.generateBoxes(this.props.nrofboxes)}
          <div className={`ms-Grid-row ${styles['separator']}`}>
            <hr className={styles["adw-separator"]} />
          </div>
          {this.state.groupByFields.map(item => {
            
            if (item.name == 'Customer' || item.name == 'SalesManager') {
              return (<ListView
                items={this.state.originalitems}
                viewFields={this._viewFields}
                groupByFields={this.state.groupByFields}
              />
              )
            } else {
              console.log('filter Clicked');
              return (
              <ListView
                items={this.state.originalitems}
                viewFields={this._viewFields}
              />)
            
            }
          })} 

Here I check if is the grouped or filtered list that needs to rend.
The item.name is the only part that I can check if this is about grouping or filtering, if the groupFileds name props has one of these names then the result needs to be grouped. That part works without problems. The filter part, the one inside the ‘else’ is the one that is not getting rendered if I click in any other button. I can’t even see the console.log

The event handler of the buttons are this

private getEnded(): void {
   this.props.provider.getEnded().then((originalitems: IList[]) => {
     this.setState({
       filteredListItems: originalitems,
     });
   });
 }

 private getPassed(): void {
   this.props.provider.getPassed().then((originalitems: IList[]) => {
     this.setState({
       filteredListItems: originalitems
     });
   });
 }

I suppouse that I am using the correct states in the right way, I always get confused when it comes to the setState.

The states are initialized in the componentDidMount :

public componentDidMount(): void {
    this.props.provider.getContent().then((originalitems: IList[]) => {
      this.setState({
        filteredListItems: originalitems,
        originalitems: originalitems
      });
    });
  }

What I am doing wrong?

Thanks!!

I found the problem. Sometimes they are so obvious that I can’t see them:
In the filtered listview I was calling the wrong state. It should use the filteredState not the original.
Now is working!

Thanks a lot for all your help!!

Have a nice day!!

1 Like

Good work! :sunglasses: