I am trying to make it so that a Component array shows the username of a user based on the ID from a database, or "DELETED" if the user does not exist. My function is working properly, and the value shows up in the logs, but the actual rendered component has an empty string where the value should be.
postsList = this.state.postsArray.map(post => {
var author = "";
AccountService.getUsernameFromId(post.author, function(id, username) {
author = username;
console.log(author);
});
return(
<Item key={post._id}>
<Item.Image size="small" src={post.image} />
<Item.Content>
<Item.Header as="a" href={"/blog/post/?id=" post._id}>{post.name}</Item.Header>
<Item.Meta>{author} | {post.date_created}</Item.Meta>
<Item.Description>{post.post_contents.slice(0, 200) "..."}</Item.Description>
</Item.Content>
</Item>
);
});
Can someone please help me with this?
CodePudding user response:
i am not sure yet what getUsernameFromId
, but I feel you're trying to make API request to server during map.
so at the start of the loop you make a request to API, component renders without waiting for an API response when the API request is resolved result is logged which is expected behavior.
You will have to declare AccountService.getUsernameFromId
as async function or make it a promise-based function.
then you can write your code like this
postsList = this.state.postsArray.map(async post => {
var author = await AccountService.getUsernameFromId(post.author);
return(
<Item key={post._id}>
<Item.Image size="small" src={post.image} />
<Item.Content>
<Item.Header as="a" href={"/blog/post/?id=" post._id}>{post.name}</Item.Header>
<Item.Meta>{author} | {post.date_created}</Item.Meta>
<Item.Description>{post.post_contents.slice(0, 200) "..."}</Item.Description>
</Item.Content>
</Item>
);
});
CodePudding user response:
it's normal, variables in js are copied by value and not reference so when you change the variable you created "author" inside your function you're actually changing a copy of the variable "author", therefore not changing the actual variable. so in your hole program, author will be equal to an empty string as you defined it the begining.
What I would suggest is, that you use hooks, specifically the useState hook, so your code will be something like this :
postsList = this.state.postsArray.map(post => {
const [author, setAuthor] = useState([]);
useEffect(() => {
let auth = ""
AccountService.getUsernameFromId(post.author, function(id, username) {
auth = username;
setAuthor(auth);
console.log(auth);
});
}, [])
return(
<Item key={post._id}>
<Item.Image size="small" src={post.image} />
<Item.Content>
<Item.Header as="a" href={"/blog/post/?id=" post._id}>{post.name}</Item.Header>
<Item.Meta>{author} | {post.date_created}</Item.Meta>
<Item.Description>{post.post_contents.slice(0, 200) "..."}</Item.Description>
</Item.Content>
</Item>
);
});