0

I'm working on a chat system, each message belongs to a user, who sent it . In the database of messages I store just the user id, and I have a problem with fetching the users names, and replace it in the message.

This is the way I tried to fetch the username, by creating a method which takes the users id, and after fetching from api returns the users name, but the return doesn't work :

<div v-for="message in messages" :key="message.id" class="message">
   <a href="#">@{{ getUserDetails(message.user_id) }}</a>
   <p>@{{ message.message }}</p>
</div>
    methods: {
        getUserDetails(id) {
            fetch('/api/user/' + id)
                .then(res => res.json())
                .then(res => {
                    return res.name;
                })
        }
    },

I hope you understand my problem, sorry for my bad english, is not my native language ...

5
  • 1
    Does this answer your question? How do I return the response from an asynchronous call? Commented Jul 7, 2020 at 11:58
  • "the return doesn't work" how not? what exactly happens? why is that wrong? Commented Jul 7, 2020 at 11:59
  • @Terry Thanks ! I'll take a look Commented Jul 7, 2020 at 12:05
  • @underscore_d It just doesn't return the username, It doesn't return nothing, but if I console.log the response, I get the names . Commented Jul 7, 2020 at 12:06
  • You should flip the problem on its head: remember that fetch is asynchronous and therefore returns a Promise instead of the value the promise is resolved with. Therefore, a better way around the issue is to actually populate your messages array with user details by calling the endpoint, for example, during the mounted() life cycle hook or the likes of it. Commented Jul 7, 2020 at 12:09

1 Answer 1

1

The problem occurs because you are actually not return anything in getUserDetails function.

You are trying to return from a then() callback. But when you return a value from that, the next then() is called with that value. The parent function getUserDetails still returns nothing.

To solve your problem, I think you should use another object to store the usernames. This way, you would not overwhelm the server by doing a request to get the username for every message.

Something like this should work:

<div v-for="message in messages" :key="message.id" class="message">
   <a href="#">@{{ getUsername(message.user_id) }}</a>
   <p>@{{ message.message }}</p>
</div>
data () {
  return {
    listUsername: {}
  }
},
methods: {
  getUsername(id)  {
    if (!this.listUsername[id]) {
      this.getUserDetails(id)
      return 'Unknown'
    }
    return this.listUsername[id]
  },
  getUserDetails(id) {
    fetch('/api/user/' + id)
      .then(res => res.json())
      .then(res => {
        this.$set(this.listUsername, id, res.name)
      })
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much !

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.