I want to create a public profile page in my application, but whenever I hit a route, an error appears in the console. I can’t understand what a problem is, could you please look at it with your fresh eyes. Let me give you more info about my issue.
Public route – back-end
// @route POST api/profile/user/:user_id
// @desc Get profile by user ID
// @access Public
router.get('/user/:user_id', (req, res) => {
const errors = {};
Profile.findOne({ user: req.params.user_id })
.populate('user', ['name', 'email', 'avatar'])
.then(profile => {
if (!profile) {
errors.nonprofile = 'There is no profile for this user';
res.status(404).json(errors);
}
res.json(profile);
})
.catch(err =>
res.status(404).json({ profile: 'There is no profile for this user' })
);
});
Redux action part
export const getPublicProfileByID = id => dispatch => {
console.log(id);
axios
.get(`api/profile/user/${id}`)
.then(res => {
dispatch({
type: GET_PUBLIC_PROFILE_BY_ID,
payload: res.data
});
})
.catch(err =>
dispatch({
type: GET_PUBLIC_PROFILE_BY_ID,
payload: null
})
);
};
PublicProfile – react part
import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Spinner from '../common/Spinner';
import { getPublicProfileByID } from '../../actions/profileActions';
import { Link } from 'react-router-dom';
class PublicProfile extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log(this.props);
this.props.getPublicProfileByID(this.props.profile._id);
}
render() {
const { profile, loading } = this.props.profile;
const { auth } = this.props;
console.log(profile);
let profileShow;
if (profile === null || loading) {
profileShow = <Spinner />;
} else {
profileShow = (
<div className="row">
<div className="col-md-4" align="center">
<figure className="figure">
<img
src={auth.user.avatar}
className="figure-img img-fluid rounded"
alt={auth.user.avatar}
/>
</figure>
</div>
<div className="col-md-6">{profile.bio}</div>
<div className="col-md-2">
<ul className="list-group list-group-flush">
<li className="list-group-item">
<div className="row">
<div className="col">
{profile.social ? (
<a href={profile.social.facebook} target="_blank">
<i className="fab fa-facebook" />
</a>
) : null}
</div>
<div className="col">
{profile.social ? (
<a href={profile.social.vk} target="_blank">
<i className="fab fa-vk" />
</a>
) : null}
</div>
<div className="col">
{profile.social ? (
<a href={profile.social.instagram} target="_blank">
<i className="fab fa-instagram" />
</a>
) : null}
</div>
</div>
</li>
{profile.country ? (
<li className="list-group-item">Страна: {profile.country}</li>
) : null}
{profile.city ? (
<li className="list-group-item">Город: {profile.city}</li>
) : null}
{profile.gender ? (
<li className="list-group-item">Пол: {profile.gender}</li>
) : null}
{profile.education ? (
<li className="list-group-item">
Образование: {profile.education}
</li>
) : null}
{profile.languages ? (
<li className="list-group-item">
Языки:{' '}
{profile.languages.map(language => (
<span key={language}>{language}</span>
))}
</li>
) : null}
</ul>
</div>
</div>
);
}
return (
<div className="container">
<div className="row">
<div className="col align-self-center">{profileShow}</div>
</div>
</div>
);
}
}
PublicProfile.propTypes = {
auth: PropTypes.object.isRequired,
getPublicProfileByID: PropTypes.func.isRequired
};
const mapStateToProps = state => ({
profile: state.profile,
auth: state.auth
});
export default connect(
mapStateToProps,
{ getPublicProfileByID }
)(PublicProfile);
Redux Reducer Part
import {
GET_PROFILE,
PROFILE_LOADING,
CLEAR_CURRENT_PROFILE,
GET_PUBLIC_PROFILE_BY_ID
} from '../actions/types';
const initialState = {
profile: null,
profiles: null,
loading: false
};
export default function(state = initialState, action) {
switch (action.type) {
case PROFILE_LOADING:
return {
...state,
loading: true
};
case GET_PROFILE:
return {
...state,
profile: action.payload,
loading: false
};
case GET_PUBLIC_PROFILE_BY_ID:
return {
...state,
profile: action.payload,
loading: false
};
case CLEAR_CURRENT_PROFILE:
return {
...state,
profile: null
};
default:
return state;
}
}
Public route in app.js
<Route exact path="/leaders/:id" component={PublicProfile} />
3
Answers
I have solved the issue, I should have used
findById
method, and params should have beenreq.params.id
. So a valid code looks like this.You are confusing your front end
URL
with backendRestful http URL
,you need to start different two ports for both react and node app,
You are mixing logic of React-Route with node-Express logic,
when
localhost:3000
stands for react,you should choose different port number for backend app,
keep server listening on that port,
then make req to that urls and communicate your data.
You need to configure your app properly.
eg.
localhost:3000/leaders/leader/2
for your front end,make server request like,
localhost:8000/api/profile/user/2
where 2 is${id}
for backend code.Just one issue I noticed, in your api route, it wants to find a
Profile
who’suser
field matches the parameter you passed.However it looks like you are passing in the wrong value in your action-creator. You’re passing in the id of the profile.
Instead, you need to pass in the id of the user who owns this profile.
Second, there appears to be an error with your
axios
call