skip to Main Content

I’m trying to build a social media site. I’ve taken some ides from 2 different tutorials I’v done. The issue I was having is that posts load when I log into the site and display on the page but when I add a new post it doesn’t show up on the page until I refresh. I’m very new to react and am really struggling with Redux. I kind of patched part of it together from both tutorials.

I like the way the one tutorial does that creat post popup like facebook and when users select images they are uploaded to cloudinary but that is the one that doesn’t update after a new post. The other one works but it only uploads to the local machine so I’m trying to combine them but it’s not working. When I create a new text it crashes.

Here is posts page that maps through the psots and pass the data to the post page:

import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { getTimeLinePosts } from '../../../actions/postAction';
import Post from '../Post/Post.js';

const Posts = () => {
  const dispatch = useDispatch();
  const { user } = useSelector((state) => state.authReducer.authData);
  const { posts, loading } = useSelector((state) => state.postReducer);

  useEffect(() => {
    dispatch(getTimeLinePosts(user._id));
  }, [dispatch, user._id]);
  return (
    <div className="Posts">
      {posts.map((post, i) => (
        <Post key={i} post={post} index={i} user={user} />
      ))}
    </div>
  );
};

export default Posts;

Here is the actual post page. It’s pretty bare bones now and works if I log in, but as soon as I add a new text it gives a big error which I will post after the page.

import './style.css';
import { useSelector } from 'react-redux';

const Post = ({ post, index }) => {
  const { user } = useSelector((state) => state.authReducer.authData);

  return <div className="post">{post.text}</div>;
};

export default Post;

Here is the error:

ERROR
Cannot read properties of null (reading 'text')
TypeError: Cannot read properties of null (reading 'text')
    at Post (http://localhost:3000/static/js/bundle.js:1727:20)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:43381:22)
    at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:46667:17)
    at beginWork (http://localhost:3000/static/js/bundle.js:47963:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:32973:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:33017:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:33074:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:52948:11)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:52195:16)
    at workLoopSync (http://localhost:3000/static/js/bundle.js:52118:9)

Now for the reduct stuff. This is my postAction:

import * as PostsApi from '../api/PostsRequests';
export const getTimeLinePosts = (id) => async (dispatch) => {
  dispatch({ type: 'RETREIVING_START' });
  try {
    const { data } = await PostsApi.getTimelinePosts(id);
    dispatch({ type: 'RETREIVING_SUCCESS', data: data });
  } catch (error) {
    dispatch({ type: 'RETREIVING_FAIL' });
    console.log(error);
  }
};

And the postRequest

import axios from 'axios';
const API = axios.create({ baseURL: 'http://localhost:8000' });
export const getTimelinePosts = (id) => API.get(`/posts/${id}/timeline`);

And the postReducer

const postReducer = (
  state = { posts: null, loading: false, error: false, uploading: false },
  action
) => {
  switch (action.type) {
    // belongs to PostShare.jsx
    case 'ADDPOST_START':
      return { ...state, error: false, uploading: true };
    case 'ADDPOST_SUCCESS':
      return {
        ...state,
        posts: [action.data, ...state.posts],
        uploading: false,
        error: false,
      };
    case 'ADDPOST_FAIL':
      return { ...state, uploading: false, error: true };
    // belongs to Posts.jsx
    case 'RETREIVING_START':
      return { ...state, loading: true, error: false };
    case 'RETREIVING_SUCCESS':
      return { ...state, posts: action.data, loading: false, error: false };
    case 'RETREIVING_FAIL':
      return { ...state, loading: false, error: true };
    default:
      return state;
  }
};

export default postReducer;

And the last part is where I actually add the post. It adds it and if I log out and come back it will be there, but there is something I’m obviously doing wrong, or a lot, but I’m trying and as I said, I’m new.

const CreatePostPopup = ({ user, setPostVisible }) => {
  const popup = useRef(null);
  const dispatch = useDispatch();
  const loading = useSelector((state) => state.postReducer.loading);
  const [text, setText] = useState('');
  const [showPrev, setShowPrev] = useState(false);
  //const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [images, setImages] = useState([]);
  //const [background, setBackground] = useState('');
  useClickOutside(popup, () => {
    setPostVisible(false);
  });

  const postSubmit = async () => {
    dispatch({ type: 'ADDPOST_START' });
    if (images && images.length) {
      const postImages = images.map((img) => {
        return dataURItoBlob(img);
      });
      const path = `facebook/${user.user.username}/post Images`;
      let formData = new FormData();
      formData.append('path', path);
      postImages.forEach((image) => {
        formData.append('file', image);
      });
      const response = await uploadImages(formData, path, user.token);

      const res = await createPost(
        null,
        text,
        response,
        user.user._id,
        user.token
      );

      //setLoading(false);
      if (res === 'ok') {
        setPostVisible(false);
        setText('');
        setImages('');
        dispatch({ type: 'ADDPOST_SUCCESS' });
      }
    } else if (text) {
      //setLoading(true);
      const res = await createPost(null, text, null, user.user._id, user.token);

      if (res === 'ok') {
        setPostVisible(false);

        setText('');
        dispatch({ type: 'ADDPOST_SUCCESS' });
      } else {
        dispatch({ type: 'ADDPOST_FAIL' });
      }
    } else {
      console.log('Nothing');
    }
  };

  return (
    <div className="blur">
      <div className="postBox" ref={popup}>
        {error && <PostError error={error} setError={setError} />}
        <div className="box_header">
          <div className="small_circle" onClick={() => setPostVisible(false)}>
            <i className="exit_icon" />
          </div>
          <span>Create Post</span>
        </div>
        <div className="box_profile">
          <img
            src={user.picture}
            alt={user.first_name}
            className="box_profile_img"
          />
          <div className="box_col">
            <div className="box_profile_name">
              {user.first_name} {user.last_name}
            </div>
            <div className="box_privacy">
              <img src="../../../icons/public.png" alt="" />
              <span>Public</span>
              <i className="arrowDown_icon" />
            </div>
          </div>
        </div>

        {!showPrev ? (
          <>
            <EmojiPickerBackgrounds
              text={text}
              setText={setText}
              user={user}
              showPrev={showPrev}
              //setBackground={setBackground}
              //background={background}
            />
          </>
        ) : (
          <ImagePreview
            text={text}
            setText={setText}
            user={user}
            showPrev={showPrev}
            images={images}
            setImages={setImages}
            setShowPrev={setShowPrev}
            setError={setError}
          />
        )}
        <AddToYourPost setShowPrev={setShowPrev} />
        <button
          className="post_submit"
          onClick={() => postSubmit()}
          disabled={loading}
        >
          {loading ? <PulseLoader color="#fff" size={5} /> : 'Post'}
        </button>
      </div>
    </div>
  );
};
export default CreatePostPopup;

There is a lot going on with that last page, but the real issue is in the postSubmit function.

Sorry this is so long but if I can get some guidance on fixing the add functionality, I would greatly appreciate it.


Please signup or login to give your own answer.
Back To Top
Search