Model dynamic properties


#1

Hello again.
Is it possible in adonis to use dynamic properties on relationships?
for example, I have the following relationship on one of my models

users () {
  return this.belongsToMany('App/Models/User')
}

is it possible to access the users into my model class with something like this: this.users so I can do further operations on this into one of my getter method?
I want to concatenate the first_name of the users as a computed property into my models class.
is this possible in adonis or I need to think of something else?

thank you, have a great day.


#2

Sorry, but I didn’t understood your question.


#3

i would like to do something like this in a computed property

this.users.map(function(elem){
    return elem.first_name;
}).join(", ");

and I am not sure how I can do it right now


#4

One thing you could do is use the .toJSON() method to convert the Lucid array into pure JSON before you run array functions on it.

let users_json = this.users.toJSON()

users_json.map(function(elem){
    return elem.first_name;
}).join(", ");

https://adonisjs.com/docs/4.0/serializers#_introduction


#5

That is true, but I am trying to access the relationship from the model not a query result
this is my relationship:

users () {
      return this.belongsToMany('App/Models/User')
  }

and in my computed property I want to do something like this

 getName () {
    return this.users.map(function(elem){
        return elem.first_name;
    }).join(", ");
  }

but is not possible and I am searching for some alternatives or something


#6

I managed to write this code into my computed property function, but it has two problems

 getName () {
    let name = ''
    this.users().fetch().then(response => {
      name = response.rows.map((user) => {
              return user.first_name
          }).join(' & ')
    }).catch()
    
    return name
  }

first one is that my query is executed twice because I call the fetch method and second, the fetch method returns a promise and so my name is always empty.

I’ve looked into hooks, specifically at afterFetch hook, which would be good for my case, but I don’t understand how to set/create a computed property from there.

Any tips?


#7

Ok, finally managed to solve this.

So I’ve used a Hook file to compute my property.
this is my hook file

SheetHook.setSheetName = async (Sheets) => {
  Sheets.map((Sheet) => {
    Sheet.name = Sheet.getRelated('users').rows.map((User) => {
      return User.first_name
    }).join(' & ')
  })
}

and in my model the computed property model became this

getName () {
  return this.name
}

Hope it will help someone :slight_smile:


#8

Thanks, you helped me!