rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

Add Virtual Attribute Type RFC

Open Tomaszal opened this issue 4 years ago • 14 comments

Slightly modified my approach from PR #7221 and created this RFC as requested.

RFC Preview Link

Tomaszal avatar Aug 16 '20 15:08 Tomaszal

I like this idea. Virtual types seem like a great way to make data more readable in the content manager.

Here are some other use cases where it would be useful:

  • Save a user's birthday, but use a virtual field to get his age
  • Save an article's slug, but use a virtual field to get a link to the full URL
  • Generate secret preview links for things like Next.js Preview mode, using the slug or id and a .env token
  • Save a relation between User and Article models, but use a virtual field to count how many articles a user has. It would also be useful to sort or filter by that field.

I'm also curious about how it would fit with the Content Types Builder. We probably won't ask the user to write a function in the CTB, but it still has to know that this field exists.

remidej avatar Aug 17 '20 08:08 remidej

Yeah those are some nice use cases, should I add them to the RFC?

Regarding how it would fit in the Content type Builder - I think it should be kept pretty simple. Only ask for a field name with no advanced settings. Perhaps also add a link to the documentation explaining what it is / how to use it.

Tomaszal avatar Aug 17 '20 12:08 Tomaszal

Referencing an article that was initiating prior the the RFC: https://github.com/strapi/strapi/pull/6433

alexandrebodin avatar Sep 04 '20 09:09 alexandrebodin

@alexandrebodin any updates on this?

Tomaszal avatar Sep 14 '20 09:09 Tomaszal

In general I would like you give more details about the content manager (can this be displayed in the list view ? how do we handle sorting, filtering ...) Do we display this field in the edit view ?

@alexandrebodin I don't really see a reason why this couldn't be displayed, sorted or filtered in the list view. I think it should be handled as regular text in there. Perhaps if the perceived 'type' of the virtual attribute for the content manager is a concern there could be an additional field virtualType. That way whenever content manager sees a virtual attribute it will handle it as it would handle an attribute of virtualType. However, I'm not sure how necessary is this (I haven't looked too deep into the content manager, so you probably know better).

If a setter is added to the virtual attribute functions then yes, this could definitely be displayed in the edit view. However then there is a problem with user being confused if both the original values and the virtual one are displayed. I.e. if user fills in first name and last name, and then fills in the full name, one thing or the other will be overridden.

Tomaszal avatar Sep 16 '20 23:09 Tomaszal

How about adding getter and setter on model’s js file?

For example on api/student/models/student.js

module.exports = {
  virtualAttributes: {
    fullName: {
      // getter
      get(model) {
        return `${model.firstName} ${model.lastName}`
      },
      // setter
      set(model, data) {
        const [firstName, lastName] = data.split(' ')
        model.firstName = firstName
        model.lastName = lastName
      },
      // For filter
      filter(options) {
        if(options.fullName) {
          const [firstName, lastName] = options.fullName.split(' ')
          options.firstName = firstName
          options.lastName = lastName
          delete options.fullName
        }
      },
      // For sort
      sort(options) {
        if(options.fullName) {
          const direction = options.fullName
          options.firstName = direction
          options.lastName = direction
          delete options.fullName
        }
      }
    }
  }
};

darron1217 avatar Oct 22 '20 08:10 darron1217

How about implement it as custom field type? Then we can create CombinedText type and define getter, setter, filter handler... etc on custom area. And then just select field type on Admin Page.

darron1217 avatar Oct 22 '20 09:10 darron1217

@Tomaszal here are some of my comments/inputs:

  • It would be most flexible to allow Promise's/async functions for generating the value incase there needs to be some async operation involved in calculating the value (dependency on another model value, external API, etc.)
  • There is another use-case (detailed below) where the attribute is actually written to the database but is never editable (i.e. the value is generated in the write lifecycle, not the read lifecycle). In my opinion we should allow for such a case. How would this be implemented in your proposal?

Use-case: value generated in write lifecycle

Consider a system that sends push notifications to users when an item is published, and it sets a notifiedAt: Date attribute with the timestamp of the notification (which is stored in the database). The notifiedAt attribute should be visible to the user so they can see if/when a notification was sent, but they can never edit it (i.e. it is "virtual").

This amplifies the need for async operations during calulation (i.e. sending a push notification).

An alternative/simple way of implementing this is just hard-coding such an attribute as readonly in the model's JSON, but it could be integrated into this proposal if it makes sense?

brettwillis avatar Dec 07 '20 23:12 brettwillis

CLA assistant check
All committers have signed the CLA.

strapi-cla avatar Jan 21 '21 13:01 strapi-cla

Any updates on this?

SvenWesterlaken avatar Jun 05 '23 06:06 SvenWesterlaken

Any updates on this?

Inaztm avatar Jun 05 '23 07:06 Inaztm

Sorry, I have not used Strapi for any projects since writing this RFC, so I do not have the relevant context to update it with the suggestions from the team. I would suggest someone to take over and update the RFC so that the Strapi team can look into it again.

Tomaszal avatar Jun 06 '23 19:06 Tomaszal

No problem @Tomaszal. I was mainly addressing the straps team in order to bring attention to this again as it would ease up a lot of data I would like to add to my models.

SvenWesterlaken avatar Jun 07 '23 07:06 SvenWesterlaken

No problem @Tomaszal. I was mainly addressing the straps team in order to bring attention to this again as it would ease up a lot of data I would like to add to my models.

Hi, this feature does look interesting but isn't something on the roadmap for the time being. Feel free to upvote and comment your specific usecase here https://feedback.strapi.io/feature-requests/p/field-type-computed :)

alexandrebodin avatar Jun 21 '23 12:06 alexandrebodin