React App Using the same function in two places but the API call is different. How do I force it to use the root everytime?

Viewed 71

So I am building an app that allows people to make posts and leave comments. I'm running into an issue where if I use the same addLikes and unLike function in two different places, the second one doesn't work.

Here is function in my action/controller file.

export const addLike = (id) => async (dispatch) => {
  try {
    const res = await axios.put(`api/posts/like/${id}`);

    dispatch({
      type: UPDATE_LIKES,
      payload: { id, likes: res.data },
    });
  } catch (err) {
    dispatch({
      type: POST_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status },
    });
  }
};

// Unlike

export const unLike = (id) => async (dispatch) => {
  try {
    const res = await axios.put(`api/posts/unlike/${id}`);

    dispatch({
      type: UPDATE_LIKES,
      payload: { id, likes: res.data },
    });
  } catch (err) {
    dispatch({
      type: POST_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status },
    });
  }
};

When I use it on the page that shows all posts from newest to oldest. The API directs to:

http://localhost:3000/api/posts/like/5ebba76c42f5fc2f98ebd94b

<Fragment>
      <div className='post bg-white p-1 my-1'>
        <div>
          <Link to={`/profile/${user}`}>
            <img className='round-img' src={avatar} alt='' />
            <h4>{name}</h4>
          </Link>
        </div>
        <div>
          <p className='my-1'>{text}</p>
          <p className='post-date'>
            Posted on <Moment format='YYYY/MM/DD'>{date}</Moment>
          </p>
          <button
            onClick={(e) => addLike(_id)}
            type='button'
            className='btn btn-light'
          >
            <i className='fas fa-thumbs-up'></i>{" "}
            <span>{likes.length > 0 && <span>{likes.length}</span>}</span>
          </button>
          <button
            onClick={(e) => unLike(_id)}
            type='button'
            className='btn btn-light'
          >
            <i className='fas fa-thumbs-down'></i>
          </button>
          <Link to={`/posts/${_id}`} className='btn btn-primary'>
            Discussion{" "}
            {comments.length > 0 && (
              <span className='comment-count'>{comments.length}</span>
            )}
          </Link>
          {!auth.loading && user === auth.user._id && (
            <button
              onClick={(e) => deletePost(_id)}
              type='button'
              className='btn btn-danger'
            >
              <i className='fas fa-times'></i>
            </button>
          )}
        </div>
      </div>
    </Fragment>

I then am currently building fragment for showing individual posts and the API directs the to:

http://localhost:3000/posts/api/posts/like/5ebba76c42f5fc2f98ebd94b

      <div className='post bg-white p-1 my-1'>
        <div>
          <Link to={`/profile/${user}`}>
            <img className='round-img' src={avatar} alt='' />
            <h4>{name}</h4>
          </Link>
        </div>
        <div>
          <p className='my-1'>{text}</p>
          <p className='post-date'>
            Posted on <Moment format='YYYY/MM/DD'>{date}</Moment>
          </p>
          <button
            onClick={(e) => addLike(_id)}
            type='button'
            className='btn btn-light'
          >
            <i className='fas fa-thumbs-up'></i>{" "}
            <span>{likes.length > 0 && <span>{likes.length}</span>}</span>
          </button>
          <button
            onClick={(e) => unLike(_id)}
            type='button'
            className='btn btn-light'
          >
            <i className='fas fa-thumbs-down'></i>
          </button>
        </div>
      </div>
    </Fragment>

The two locations are:

              <PrivateRoute exact path='/posts' component={Posts} />
              <PrivateRoute exact path='/posts/:id' component={Post} />

How do I force the same function to use the same exact path every time instead? I'm not sure why the second situation adds the extra /posts in front of api/

2 Answers

You have to set and config the default base URL for Axios request.

For ex:

// Axios configuration
axios.defaults.baseURL = "https://example.com/";

Now, whenever you make your request it will automatically prefix this default baseURL to your every request.

Like: axios.put(api/posts/like/${id}) to axios.put(https://example.com/api/posts/like/${id});

  • How come you are sending an Id on the addLike method. If you are creating a like you shouldn’t have its id. And the verb should be post, not put.
  • the route /posts/:id shouldn’t be exact, because :id is dynamic.
  • <span>{likes.length > 0 && <span>{likes.length}</span>}</span> what is the purpose behind this line ?? Shouldn’t it be:
....
render () {
....
const likes = likes.length;
return (
....
<span>{likes}</span>
  • there are some gaps. What kind of Router you are using ?
  • How are you setting axios ? I recommend you to use npm i axios-es6-class
Related