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 ...

  • 1
    Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Terry Jul 07 '20 at 11:58
  • "the return doesn't work" how not? what exactly happens? why is that wrong? – underscore_d Jul 07 '20 at 11:59
  • @Terry Thanks ! I'll take a look – Pricop George-Tiberiu Jul 07 '20 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 . – Pricop George-Tiberiu Jul 07 '20 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. – Terry Jul 07 '20 at 12:09

1 Answers1

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)
      })
  }
}
thks173
  • 1,500
  • 1
  • 8
  • 6