Home > database >  Async function call inside jsx
Async function call inside jsx

Time:10-11

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;

CodePudding user response:

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();
}, []);
...

CodePudding user response:

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

    useEffect(() => {
        const fetchMyData = async () => {
            const commentsFromDb = await getComments();
            commentsFromDb = commentsFromDb.map(async comment=>{
                comment.author = await getAuthor(comment.authorId)
                return comment;
            })
            setComments(commentsFromDb);
        };
         fetchMyData();
    }, []);



 return (
        <>
            <h1>Komentarze</h1>
            <div className="comments">
                {comments.filter((comment) => comment.placeId === placeId).reverse().map(async (comment) => (
                    <div className="comment">
                        <p>
                            author:
                            {' '}
                            {comment.author.profilePhoto}
                        </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} />
        </>
    );

  • Related