1

I have two APIs which are written in action and reducer using redux.The first api fetches a list of user and the second api based on user id which comes from the first api.

The APIs are as follows action.js

export const GET_EXPERT_LIST='GET_EXPERT_LIST';
export const GET_PROFILE_PHOTO='GET_PROFILE_PHOTO';
export const getExpertList=()=>{
    return(dispatch)=>{
        axios({
            method:'POST',
            url:Constants.URLConst+"/xyz",
            headers:Constants.headers,
            data:{
                "PageNum" : 1,
            }
        }).then((response)=>{
            return dispatch({
                type:GET_EXPERT_LIST,
                response
            })

        }).catch((error)=>{
            console.log(error);
        })
    }
}

export const getProfile=(userid)=>{
    return(dispatch)=>{
        axios({
             method:'GET',
             url:Constants.URLConst+"/UserProfileImage?enterpriseId="+userid,
             headers:Constants.headers
        }).then((response)=>{
             dispatch({
                type:GET_PROFILE_PHOTO,
                response
             })
        }).catch((error)=>{
            console.log(error);
        })
    }
}

And in reducer.js, I have-

import {combineReducers} from 'redux';
import {ASK_EXPERT_DATA,GET_EXPERT_LIST,GET_PROFILE_PHOTO} from '../actions/ProfilePageActions.js';

export function getExpertList(state={},action){
    switch(action.type){
        case GET_EXPERT_LIST:
            return {...state, ...action.response}
            default:
                return state
    }
} 

export function getProfile(state={},action){
    switch(action.type){
        case GET_PROFILE_PHOTO:
            return {...state, ...action.response}
            default:
                return state
    }
}

const data=combineReducers({
    getExpertList,
    getProfile
})

export default data;

In the main javascript file, I am calling the first api in componentDidMount, since the first api return an array which I am using map() for display.

import React,{Component} from 'react';
import ReactDom from 'react-dom';
import {getExpert,getExpertList} from './actions/ProfilePageActions.js';
import {connect} from 'react-redux';
import theme from './assets/react-toolbox/theme';
import ThemeProvider from 'react-toolbox/lib/ThemeProvider';
import Card from 'react-toolbox/lib/card/Card.js';
import CardTitle from 'react-toolbox/lib/card/CardTitle';
import CardMedia from 'react-toolbox/lib/card/CardMedia';
import Chip from 'react-toolbox/lib/chip/Chip.js';
import CardText from 'react-toolbox/lib/card/CardText';

class FindExpert extends Component{

    state={
        countries: ['ES-es', 'TH-th'],
        source:[],
        valueSelected:[],
        experts:[]
    }   

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

    componentWillReceiveProps(nextProps){

        if(nextProps.get_Expert_List && nextProps.get_Expert_List.data){
            this.setState({
                experts:[...nextProps.get_Expert_List.data.Experts] 
            })
        }
    }

    getExpertInfo(){
        var i=1;
        if (this.state.experts && this.state.experts.length) {
            this.test = this.state.experts.map((expertUSer)=> {
                this.props.getProfile(expertUSer.UserId);
                console.log(this.props.get_profile);
                return(
                    <ThemeProvider theme={theme} key={i++}>
                        <Card className='experts'>

                            <CardTitle title={expertUSer.Name}
                                subtitle={expertUSer.Designation}/>
                            <CardText>{expertUSer.Country}</CardText>
                        </Card>
                    </ThemeProvider>
                    )
            });

            return this.test;
        }
        return null;
    }

    render(){
        if(this.props.ask_expert.data){
            return(
                <div className='expert-div' id='expert-div'>{this.getExpertInfo()}</div> 
                    )
        }else{
            return null;
        }
    }
}

const mapStateToProps=(state)=>{
    console.log({getExpert: state.getProfile});
    return{
        get_Expert_List:state.getExpertList,
        get_profile:state.getProfile
    }
}

export default connect(mapStateToProps,{
    getExpertList,
    getProfile
})(FindExpert);

So,in getExpertList's data, I am calling the getProfile by passing the user id of the individual user.But in this.props.getProfile(expertUSer.UserId);, I get the error that

getProfile is not a function

erro

What should be done here?

Tomasz Mularczyk
  • 34,501
  • 19
  • 112
  • 166
Aayushi
  • 1,736
  • 1
  • 26
  • 48
  • Duplicate: https://stackoverflow.com/questions/30148827/this-is-undefined-inside-map-function-reactjs – Rick Jolly Nov 14 '17 at 16:43
  • It's not a duplicate. If you go through the problem, I am using map() correctly, I am just not able to call an api from inside the map using redux @RickJolly – Aayushi Nov 14 '17 at 16:46
  • 1
    No, you are not using map correctly. The error `cannot read props of undefined` is because `this` is undefined. So either pass it in as a second arg to `map` or use an arrow function. – Rick Jolly Nov 14 '17 at 16:48
  • I have updated the question, please check! – Aayushi Nov 14 '17 at 16:53
  • Should have created a new question instead of totally changing it. But you call your function two different names: `get_profile:state.getProfile`. You should also probably be using `mapDispatchToProps`. – Rick Jolly Nov 14 '17 at 16:57

2 Answers2

2

I see that you pass getProfile in connect but... it is not imported. xD

try:

import {getExpert,getExpertList, getProfile} from './actions/ProfilePageActions.js';
Tomasz Mularczyk
  • 34,501
  • 19
  • 112
  • 166
1

Pass current context to map:

this.state.experts.map(function(expertUSer) {...}, this)

So your getExpertInfo() looks like this:

getExpertInfo(){
    var i=1;
    if (this.state.experts && this.state.experts.length) {
        this.test = this.state.experts.map((expertUSer)=> {
            this.props.getProfile(expertUSer.UserId);
            console.log(this.props.get_profile);
            return(
                <ThemeProvider theme={theme} key={i++}>
                    <Card className='experts'>

                        <CardTitle title={expertUSer.Name}
                            subtitle={expertUSer.Designation}/>
                        <CardText>{expertUSer.Country}</CardText>
                    </Card>
                </ThemeProvider>
                )
        }, this);

        return this.test;
    }
    return null;
}
Martin
  • 4,042
  • 2
  • 19
  • 29