user10408806
user10408806

Reputation:

How to Filter array from state onChange based on category and revert to default?

For my class based component, I have a state object that contains a defined array named movies. I also have a handleMoviesFilter function, that is called onChange on the select tag.

How can I filter the options dynamically from my array, filter them onChange.. and revert when I pick another movie?

state = {
    movies: [
        {
            name: 'Goodfellas',
            category: 'crime'
        },

        {
            name: 'Saving private ryan',
            category: 'war'
        },
        {
            name: 'The Shawshank Redemption',
            category: 'drama'
        }
    ]
}

handleMoviesFilter = e => {
    let currentMovie = e.target.value;

    const updateMoviesState = this.state.movies.filter(({ category }) =>
        currentMovie.includes(category)
    );

    this.setState({
        opleidingen: updateMoviesState,
        isResetButtonActive: true,
    });
}

<select id="lang" onChange={this.handleMoviesFilter}>
    <option value="select">Select</option>
    <option value="Goodfellas">Goodfellas</option>
    <option value="Saving private ryan">Saving private ryan</option>
    <option value="The Shawshank Redemption">The Shawshank Redemption</option>
</select>

Upvotes: 1

Views: 3412

Answers (2)

bitznbytez
bitznbytez

Reputation: 106

If what you are trying to accomplish is based upon the selected option, filter the state.movies and return those in which match, then you would want to do something like the following...

state = {
    movies: [
        {
            name: 'Goodfellas',
            category: 'crime'
        },

        {
            name: 'Saving private ryan',
            category: 'war'
        },
        {
            name: 'The Shawshank Redemption',
            category: 'drama'
        }
    ]
}

handleMoviesFilter = e => {
    let currentMovie = e.target.value;

    const updateMoviesState = this.state.movies.filter(movie => movie.name.toLowerCase() === currentMovie.toLowerCase());

    this.setState({
        movies: updateMoviesState,
        isResetButtonActive: true,
    });
}

<select id="lang" onChange={this.handleMoviesFilter}>
    <option value="select">Select</option>
    <option value="Goodfellas">Goodfellas</option>
    <option value="Saving private ryan">Saving private ryan</option>
    <option value="The Shawshank Redemption">The Shawshank Redemption</option>
</select>

Upvotes: 2

codeherk
codeherk

Reputation: 1657

You would want to

  • get the selected value
  • uppercase all of it's characters with toUpperCase()
  • filter state to get the movies that includes the selected value in it's name
    • filter & includes method used
state = {
    movies: [
        {
            name: 'Goodfellas',
            category: 'crime'
        },

        {
            name: 'Saving private ryan',
            category: 'war'
        },
        {
            name: 'The Shawshank Redemption',
            category: 'drama'
        },
        {
            name: 'Good Riddance',
            category: 'drama'
        }
    ]
}

handleMoviesFilter = e => {
    let currentMovie = e.target.value.toUpperCase();


    //const updateMoviesState = this.state.movies.filter(movie => movie.name.toUpperCase() === currentMovie);

    const updateMoviesState = this.state.movies.filter(movie => movie.name.toUpperCase().includes(currentMovie));
    this.setState({
        movies: updateMoviesState,
        isResetButtonActive: true,
    });
}

<select id="lang" onChange={this.handleMoviesFilter}>
    <option value="select">Select</option>
    <option value="Goodfellas">Goodfellas</option>
    <option value="Saving private ryan">Saving private ryan</option>
    <option value="The Shawshank Redemption">The Shawshank Redemption</option>
</select>

Test It Out

This snippet was made so you can test it out. This does NOT include react-js framework of course.

const state = {
    movies: [
        {
            name: 'Goodfellas',
            category: 'crime'
        },

        {
            name: 'Saving private ryan',
            category: 'war'
        },
        {
            name: 'The Shawshank Redemption',
            category: 'drama'
        },
        {
            name: 'Good Riddance',
            category: 'drama'
        }
    ]
}

handleMoviesFilter = e => {
    // get requested movie
    let currentMovie = document.getElementById('textField').value.toUpperCase(); // t
    console.log("Requested Movie:", currentMovie);
    
    // array has a movie that equals selected movie
    //const updateMoviesState = state.movies.filter(movie => movie.name.toUpperCase() === currentMovie);

    // array has a movie whose name contain the phrase 
    const updateMoviesState = state.movies.filter(movie => movie.name.toUpperCase().includes(currentMovie));

    console.log("Filter Result:", updateMoviesState);
}
<input id="textField"></input>
<button onclick="handleMoviesFilter(event)">Filter</button>

Upvotes: 0

Related Questions