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