items not being displayed on table

Tags: , , ,



I’ve been trying to create this search app where I can display the items in a table and delete items using react redux. However, on the initial load, the app shows a table but there is no data in the table. It’s an empty table. If i search for another movie name which have more than one movie for that search term, then 2 tables would be shown but I want to show everything on the same table itself. The delete button is not working as well. Is there something wrong with my action and reducer files?

Action.js

import {
  FETCH_MOVIE_PENDING,
  FETCH_MOVIE_SUCCESS,
  FETCH_MOVIE_ERROR,
  DELETE_MOVIE
} from "./types";

const fetchMoviePendig = () => ({
  type: FETCH_MOVIE_PENDING
});

const fetchMovieSuccess = json => ({
  type: FETCH_MOVIE_SUCCESS,
  payload: json
});

const fetchMovieError = error => ({
  type: FETCH_MOVIE_ERROR,
  payload: error
});

export const fetchMovie = name => {
  return async dispatch => {
    dispatch(fetchMoviePendig());
    try {
      const url = `https://jsonmock.hackerrank.com/api/movies/search/?Title=${name}`;
      const response = await fetch(url);
      const result = await response.json(response);

      console.log(result);
      dispatch(fetchMovieSuccess(result.data));
    } catch (error) {
      dispatch(fetchMovieError(error));
    }
  };
};

export const deleteEvent = id => async dispatch => {
  try {
    dispatch({
      type: DELETE_MOVIE,
      payload: id
    });
  } catch (err) {
    console.log(err);
  }
};

Reducer

import {
  FETCH_MOVIE_PENDING,
  FETCH_MOVIE_SUCCESS,
  FETCH_MOVIE_ERROR,
  DELETE_MOVIE
} from "../action/types";

const initialState = {
  data: [],
  loading: false,
  error: ""
};

const moviesReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_MOVIE_PENDING:
      return {
        ...state,
        loading: true
      };
    case FETCH_MOVIE_SUCCESS:
      return {
        ...state,
        loading: false,
        data: [...state.data, action.payload]
      };
    case FETCH_MOVIE_ERROR:
      return {
        ...state,
        loading: false,
        error: action.payload
      };
    case DELETE_MOVIE:
      return {
        ...state,
        data: state.data.filter(movie => movie.id !== action.payload)
      };
    default:
      return state;
  }
};

export default moviesReducer;

App.js

import React, { Component } from "react";
import { connect } from "react-redux";
import { fetchMovie } from "./action/movieActions";

import Input from "./components/Input";
import MovieTable from "./components/MovieTable";

class App extends Component {
  state = {
    searchInput: "The Rain"
  };

  componentDidMount() {
    this.props.getMovieList(this.state.searchInput);
  }

  _getMovie = () => {
    this.props.getMovieList(this.state.searchInput);
  };

  _onChangeHandler = e => {
    this.setState({
      searchInput: e.target.value
    });
    console.log(this.state.searchInput);
  };
  render() {
    const { data, loading } = this.props.movies;
    return (
      <div className="center">
        <div>
          <h2 className="center white-text">Movie Search</h2>
        </div>

        <div className="container">
          <Input
            value={this.state.searchInput}
            onChange={this._onChangeHandler}
            onClick={this._getMovie}
          />
          <div className="row">
            {loading ? (
              <p>Loading</p>
            ) : (
              data.map(item => (
                <MovieTable
                  key={item.imdbID}
                  year={item.Year}
                  name={item.Title}
                  movieId={item.imdbId}
                />
              ))
            )}
          </div>
        </div>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    movies: state.movies
  };
};

const mapDispatchToProps = dispatch => {
  return {
    getMovieList: name => dispatch(fetchMovie(name))
  };
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(App);

Answer

Hello please take a look at the sandbox : https://codesandbox.io/s/prod-wind-4hgq2?file=/src/App.js

I have edited

 <MovieTable
        data={data.map(d => ({
          year: d.Year,
          name: d.Title,
          movieId: d.imdbId
        }))}
      />

and

case FETCH_MOVIE_SUCCESS:
  return {
    ...state,
    loading: false,
    data: action.payload
  };

And … Currently the delete button has no event, that’s why it can’t work



Source: stackoverflow