1
votes

I'm trying to map this array but the it keeps saying .includes is undefined. I assume maybe its because I've mapped is wrong? I'm not sure but I will list everything I have.

Here is what my api data looks like when I console.log(this.props.tournaments it from from my redux store: console.log

You see the undefined in the first index of the array, I've used an Object.keys(tournaments).map(key => tournaments[key]) and .map (which you can see in the component snippet below) twice which when I console.log I get the correct results but I still get an error when its passes through the .filter function.

Here is what it looks like after I've formatted the array: console.log after formatting

but I'm still getting an error...

This the error I'm getting:

Error message

Here is the component in question:

import React from 'react';
import { connect } from 'react-redux';
import { fetchTournaments } from '../actions/tournaments';

class Search extends React.PureComponent {
  // State only needs to hold the current filter text value:

  componentDidMount() {
    this.props.fetchTournaments();
  }

  state = {
    filterText: ''
  };

  handleChange = event => {
    this.setState({ filterText: event.target.value });
  };

  render() {

    let tourns = this.props.tournaments.map(tore =>
      tore.map(room => room.name)
    );

    console.log(tourns, 'here');
    const filteredList = tourns.filter(item =>
      item.name.includes(this.state.filterText)
    );

    return (
      <React.Fragment>
        <input onChange={this.handleChange} value={this.state.filterText} />
         <ul>{filteredList.map(item => <li key={item.id}>{item.name}</li>)}</ul>
      </React.Fragment>
    );
  }
}

function mapStateToProps({ tournaments }) {
  return {
    tournaments: Object.keys(tournaments).map(key => tournaments[key])
  };
}

export default connect(mapStateToProps, {
  fetchTournaments
})(Search);

My data is coming from redux like so: Reducer:

import _ from 'lodash';

import {
  FETCH_TOURNAMENT,
 from '../actions/types';

export default (state = {}, action) => {
  switch (action.type) {
    case FETCH_TOURNAMENT:
      return { ...state, [action.payload.id]: action.payload };
    default:
      return state;
  }
};

action:

import {
  FETCH_TOURNAMENT,
} from './types';

import { API_TOURNAMENTS_URL } from '../constants/api';
import axios from 'axios';

export const fetchTournament = id => async dispatch => {
  const response = await axios.get(`http://localhost:4000/tournaments/${id}`);

  dispatch({ type: FETCH_TOURNAMENT, payload: response.data });
};
1

1 Answers

0
votes

I think you could treat you response.data before setting to state to reflect more how you will be handling your application. I would imagine that you would rather have an array of objects.

you could try passing to payload Object.values(response.data).flat() instead which would give you an array of of objects based on your response.

Edit

below is without implementing Object.values(response.data).flat(). if you follow the suggestion you shouldnt need to treat

about the issue at filter, item is an array containing name value at index 0. this is why you get undefined. this happens because of tore.map(room => room.name) returns an array.

if you change as below you may get your array of tourns:

let tourns = this.props.tournaments.flat();

but I would consider to treat your response which would avoid all these changes on component level. pick one which suits you better.