Home > Enterprise >  Filter array that comes from backend in typescript
Filter array that comes from backend in typescript

Time:05-03

I have ask another questions. But I get all unuse answer. I actually not getting proper solutions.

Here I get an array from backend using redux.

const { movies, message } = useAppSelector(state => state.movies);

Here in state.movies has an object of two fields. One is movies and another is message. I defined type when I create redux reducers. Here in component I just getting this. movies type is array (Actually I am geting an array from backend by this movies field). message type is string.

In one word. here movies is array and message is string. I found this two field on state.movies.

Now I want to filter this movies-

const mathches = movies.filter((movie: movie ) => {
    const escapeRegExp = (str: string) => str.replace(/[\-\[\]\/\{\}\(\)\*\ \?\.\\\^\$\|]/g, "\\$&")
    const regex = new RegExp(escapeRegExp(search), "gi");
    return movie.name.match(regex);
})

But Here I am getting one error like- Property 'filter' does not exist on type 'never'.

Here I can understand the problem. Problem is movies is array that cant understand typescripts. I have to define or tell that movies field is array. But how can I tell or define it.

Here is full component-

import type { NextPage } from "next";
import { useState, useEffect } from "react";
import { Container } from "@mui/material";
import { GetServerSideProps } from "next";

//Redux
import { wrapper } from "Redux/Store";
import { getMovies } from "Redux/Action/movieAction";
import { useAppSelector } from "Redux/Hook";

//Components
import Search from "Components/Movies/Search";
import Lists from "Components/Movies/Lists";

type movie = {
    name: string;
    image: string;
    releaseDate: string;
    watchedDate: string;
}

const Movies: NextPage = () => {
    const { movies, message } = useAppSelector(state => state.movies);
    const [movieList, setMovieList] = useState<[]>(movies);
    const [search, setSearch] = useState<string>("");
    useEffect(() => {
        let mathches = []
        if (search.length > 0) {
            mathches = movies.filter((movie: movie ) => {
                const escapeRegExp = (str: string) => str.replace(/[\-\[\]\/\{\}\(\)\*\ \?\.\\\^\$\|]/g, "\\$&")
                const regex = new RegExp(escapeRegExp(search), "gi");
                return movie.name.match(regex);
            })
        }
        setMovieList(mathches);
    }, [search, movies])
    return (
        <Container maxWidth={false} disableGutters>
            <Search setSearch={setSearch} />
            <Lists movies={movieList} />
        </Container>
    );
};
export default Movies;

CodePudding user response:

I see two problems here.

  1. Your state definition has wrong generic type
  2. useAppSelector is returning never type

The solution to the first problem would be to define movieList state with proper type like this:

const [movieList, setMovieList] = useState<movie[]>(movies); 

As for the second problem, verify that you have defined your redux-toolkit types properly, see docs here: https://redux-toolkit.js.org/tutorials/typescript#define-root-state-and-dispatch-types

If all else fails, you can cast your hook return type to a custom type like this:


type MovieReducer = {
  movies: movies[];
  message: string; // check if this is the correct type
}


const { movies, message } = useAppSelector((state) => state.movies) as unknown as MovieReducer;

  • Related