0

I'm trying to create a search bar with React and redux. I have placed the search bar in one component (clientsearch.js) and the results in another (Clientdevicelocate.js)

I get a 'TypeError: Cannot read property 'map' of undefined' error on the line with the 'location.map'. It seems like I am not passing an initial state of "". I am a newbie to Redux and this is my first attempt at passing asynchronous code.

clientdevicelocate.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

import './Clientdevicelocate.css';
import {Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn,} from 'material-ui/Table';

class clientDevicelocate extends Component { 

    render () {
        let locations = this.props.location;  
    console.log('====================================');
    console.log('Locations', locations);
    console.log('====================================');
        return(
            <div>            
                <Table>
                    <TableHeader>
                        <TableRow>
                            <TableHeaderColumn>Device Alias</TableHeaderColumn>
                            <TableHeaderColumn>Device Serial Number </TableHeaderColumn>
                            <TableHeaderColumn>Device IMEI</TableHeaderColumn>
                            <TableHeaderColumn>Locate Address</TableHeaderColumn>
                            <TableHeaderColumn>Locate Date</TableHeaderColumn>
                            <TableHeaderColumn>Locate Time</TableHeaderColumn>
                        </TableRow>
                    </TableHeader>

                    <TableBody>
                    {locations.map(function(location, i){
                        return <TableRow key={location.numVehicleDeviceID}>
                            <TableRowColumn>{location.txtAlias}</TableRowColumn>
                            <TableRowColumn>{location.txtSMSDeviceSN}</TableRowColumn>
                            <TableRowColumn>{location.IMEI}</TableRowColumn>
                            <TableRowColumn>{location.fullAddress}</TableRowColumn>
                            <TableRowColumn>{location.date}</TableRowColumn>
                            <TableRowColumn>{location.time}</TableRowColumn>
                        </TableRow>
                    })}
                    </TableBody>
                </Table>
            </div>
        );
    }
}

const mapStateToProps = state => {
    return{
        loactions: state.locations
    };
}

export default connect(mapStateToProps)(clientDevicelocate);

clientReducer.js

import * as actionTypes from '../actions/actionTypes';

const intialState ={
        client: {
            numClientID:'',
            txtName:''
    }
};

const clientReducer = (state = intialState, action) => {
    switch(action.type){
        case actionTypes.SEARCH_CLIENT:
            return{
                ...state, 
                client:{
                    ...state.client,                       
                }
            };

        default:
            return state;
    }
}

export default clientReducer;

searchClientAction

I cleared the API call line. The API works fine and we have been using it in postman and directly in clientdeviceloacte.js prior to moving the code to redux.

import * as actionTypes from './actionTypes';
import axios from 'axios';


export const setClient = (value) => {
    return{
        type: actionTypes.SEARCH_CLIENT,
        client: value,

    }
};

export const fetchClientFailed = () => {
    return {
        type: actionTypes.FETCH_CLIENT_FAILED
    }
}

export const fetchClient = (value) => {
    return dispatch => {
        axios({
            method: 'post',
            url: 'http://.../.../getDeviceLocation',
            data:   {
                "numClientID" : value,
                "numContactID" : null,
                "ynActive" : true
                }
            })
        .then((response) => {
            console.log(response)
            let locations = response.data;
            for(let i=0; i<locations.length; i++){
                let location = locations[i];
                locations[i].fullAddress = location.txtAddress + ', '+ location.txtCity + ', ' + location.txtState + ' ' +location.txtZip;
                locations[i].date = location.dtDate.substring(0,10);
                locations[i].time = location.dtDate.substring(11, 19);
            }
            dispatch(setClient(locations));
            // this.setState({locations: locations});
            })
        .catch ( error => {
                dispatch(fetchClientFailed());
            });
        } 
    };

Clientsearch.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

import { setClient} from '../../store/actions/indexAction';

 class SearchBar extends Component {

  render() {
    const {fetchClient,value} = this.props;
    return (
      <input 
        className = 'form-control'
        placeholder = 'Search Client'
        onChange = {(e) => fetchClient(e.target.value)}
        value = {value} />
    );
  }
}

const mapStateToProps = state => {
  return {
    value: state.locations
  };

}

const mapDispatchToProps = dispatch => {
  return bindActionCreators({setClient}, dispatch);  
}

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

2 Answers 2

2

You can try constructing an initial state of an empty array for locations in your clientDevicelocate component.

export default class clientDevicelocate extends Component{
  constructor(props){
    this.state = {
      locations:[],
    }
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Same error after adding : constructor(props){ super() this.state = { locations:[], } }
0

I needed to pass an empty array in the clientReducer.js in the initialState.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.