0

I try to call the getAuthor function, inside the function (line 24 -console.log) everything is ok, but I don't know how I should call the getAuthor function (line 37) properly.

This is a component with Comments, in my database, inside the comment record I have only authorId, so I want to call the getUser(authorId) function to get other information, like profilePhoto, name etc.

   /* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
/* eslint-disable no-underscore-dangle */
/* eslint-disable import/no-cycle */
/* eslint-disable jsx-a11y/anchor-is-valid */
import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { getComments, getUser } from '../../actions/FetchData';
import '../../scss/base/_comments.scss';
import CommentForm from './CommentForm/CommentForm';

function Comments({ placeId }) {
  const [comments, setComments] = useState([]);
  useEffect(() => {
    const fetchMyData = async () => {
      const commentsFromDb = await getComments();
      setComments(commentsFromDb);
    };
    fetchMyData();
  }, []);

  const getAuthor = async (authorId) => {
    const authorFromDb = await getUser(authorId);
    console.log(authorFromDb.profilePhoto);
    return authorFromDb;
  };

  return (
    <>
      <h1>Komentarze</h1>
      <div className="comments">
        {comments.filter((comment) => comment.placeId === placeId).reverse().map((comment) => (
          <div className="comment">
            <p>
              author:
              {' '}
              {getAuthor(comment.authorId)}
            </p>
            <p>
              subject:
              {' '}
              {comment.subject}
            </p>
            <p>
              date:
              {' '}
              {comment.date}
            </p>
            <p>
              message:
              {' '}
              {comment.message}
            </p>
            <p>
              o:
              {' '}
              {comment.placeId}
            </p>
          </div>
        ))}
      </div>
      <CommentForm placeId={placeId} />
    </>
  );
}

Comments.propTypes = {
  placeId: PropTypes.string.isRequired,
};

export default Comments;

2 Answers 2

1

I recommend that when you get the comments to map the comments and request the authors for the comments and then add a new property to your comment object that represents the author and then in render you can access the author properties easily

import "./styles.css";
import { useEffect, useState } from "react";

export default function App() {
  const [comments, setComments] = useState([]);
  const placeId = 1;

  async function getComments() {
    return [
      {
        placeId: 1,
        authorId: 1,
        subject: "subject",
        date: "21-2-2020"
      }
    ];
  }

  async function getUser(id) {
    return { profilePhoto: "Hi there", name: "Ob616" };
  }

  useEffect(() => {
    getComments().then(async (commentsFromDb) => {
      for (let index = 0; index < commentsFromDb.length; index++) {
        const comment = commentsFromDb[index];

        comment.author = await getAuthor(comment.authorId);
      }

      console.log(commentsFromDb);
      setComments(commentsFromDb);
    });
  }, []);

  const getAuthor = async (authorId) => {
    const authorFromDb = await getUser(authorId);
    console.log(authorFromDb.profilePhoto);
    return authorFromDb;
  };

  return (
    <>
      <h1>Komentarze</h1>
      <div className="comments">
        {comments
          .filter((comment) => comment.placeId === placeId)
          .reverse()
          .map((comment) => (
            <div className="comment">
              <p>author: {comment.author.name}</p>
              <p>subject: {comment.subject}</p>
              <p>date: {comment.date}</p>
              <p>message: {comment.message}</p>
              <p>o: {comment.placeId}</p>
            </div>
          ))}
      </div>

      <CommentForm placeId={placeId} /> 
    </>
  );
}


Sign up to request clarification or add additional context in comments.

8 Comments

I think that's it a good solution, but I have still problem when I try save comments "setComments(commentsFromDb)", inside "commnents" I have Promises, how can I get to PromiseResult? (Promises are fulfilled)
Try this useEffect(() => { let mounted = true; getComments().then(commentsFromDb => { if (mounted) { commentsFromDb = commentsFromDb.map(async comment => { comment.author = await getAuthor(comment.authorId) return comment; }) setComments(commentsFromDb); } }); return () => mounted = false; }, []);
It's still this same
Check this code Sandbox, I made it working there SandBox
To be honest, I don't understand solution from this SandBox. Is it certainly proper version of code? Where do you add 'author' to 'comment' like here 'comment.author = await getAuthor(comment.authorId)' etc?
|
1

You can't call async function in JSX, it will return a promise. You have to resolve the promise first.

One solution is to do the same thing you did with comments, (putting it useEffect hook)

Like this:

...
const [comments, setComments] = useState([]);
const [author, setAuthor] = useState([]);
useEffect(() => {
  const fetchMyData = async () => {
    const commentsFromDb = await getComments();
    setComments(commentsFromDb);
    const authorFromDb = await getAuthor(commentsFromDb.authorId);
    setAuthor(authorFromDb );
  };
  fetchMyData();
}, []);
...

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.